JS语言核心学习心得
逻辑运算符 && ||
与其他语言相同,js中的与/或表达式由两个子表达式组成并参与逻辑运算,但是却有两点除外。
一:子表达式的值可以是任意类型
二:逻辑表达式返回其中一个子表达式的值,而不是单纯的boolean值。
因此与/或运算时,运算结果非布尔值的子表达式需要转换为布尔值。逻辑运算的结果也不一定总是true或fasle,而可能是任意数据类型的值。
这样的话,与或运算符更像是条件表达式的缩写:
a || b <==>(全等于) a ? a : b; 注意当a为true时,表达式b不予以计算。
a && b <==> (全等于) !a ? a : b; 注意当a为false时,表达式b不予以计算。
转换为boolean值
在JS中,其他数据类型的值和布尔值之间的转换关系如下所示:(可以通过逻辑非!进行测试)
所有的对象,包括[],{} | true |
null,undefined,空字符串,数字0, NaN | false |
面向对象
1. js中的对象本质上是一个字典表,没有固定大小的内存模型,相当于传统OO中的hashtable或directory,因此才可以动态的增加或删除对象中的成员。静态OO语言中的对象则有着固定的内存大小,是通过预先定义的类(Class)模板创建的。类的作用之一,就是方便用户自定义数据类型,用于在编译时期确定类型的内存空间。然而,js对象是动态的无固定内存大小的字典表,所以js中不需要类。
2. js和静态OO语言一样,是通过new关键字创建对象的,然而js中的new关键字创建的是一个空的字典表,字典表中没有任何的名值对。静态OO语言创建对象时,new关键字后面要跟一个类的名称,即new Object(),用于在编译时确定该对象的类型。js对象是动态的对象,是不需要在编译时确定类型的,但是js创建对象的语法依然是new Object()形式。此处的Object并不是类,而是函数,是构造函数。new创建了一个空对象,之后把空对象传给了Object函数,由其对该对象做初始化操作,因此Object函数中的this引用的就是new创建的对象。
3. 对象的创建过程。对象的创建分为两个步骤,一是用new操作符分配空间,二是调用构造函数初始化。new操作符也做了两件事情,一是创建了一个空对象,二是为空对象关联了prototype(即确定继承关系)。再次强调!为对象关联prototype是new完成的,而不是由构造函数完成的,尽管prototype是和构造函数相关联的。构造函数仅仅只做了一件事情,就是为传进来的this对象初始化实例属性。综上可知,如果从js实现的角度来讲,对象中实际存在着两种数据,一种是程序员自己添加的数据(field和method),另一个是对程序员透明的属性(在chrome中为__proto__,用来指向该对象的prototype,每个对象都有个隐含的__proto__属性,从而根据prototype链条实现继承链,实现作用域链)。__proto__属性由new操作符根据构造函数的prototype属性来赋值,对象创建后,__proto__不能再改变。因此对于继承来说,js并不是动态的,js的动态体现在可以随时修改和删除对象内的属性,而继承关系一经创建不能再修改。
4.js最基本的设施就是函数,函数是其第一元素。函数是特殊的对象,拥有对象的一切特性。函数的特殊在于函数的表现形式上,它可以存放执行的代码,代码可以通过函数名字来调用,仅此而已。函数的内存模型也是一个字典表,字典表中存放着函数特有的属性和方法,比如name,arguments,caller,length,prototype等。
5.所有对象的最终原型对象为Object.prototype,所有函数的原型对象是Function.prototype,在chrome中,Function.prototype = function Empty(), Empty函数的原型对象依然是Object。
6.构造函数于用其创建的对象之间的关系,仅仅在于构造函数中用this关键字的代码,以及构造函数的prototype属性。
7.对象不能访问prototype中被覆盖的方法,因为对象中__proto__对程序员是透明的,因此不能象标准OO语言中,用base或者super关键字访问父对象。