以下内容摘自JavaScript the Good Parts,列出了一些比较疑惑的地方。
语法
- 在JavaScript中以下的值返回false:
- false
- null
- undefined
- The empty string ''
- The number 0
- The number NaN
All others values are truthy, including true, the string 'false', and all objects.
- 使用
||
运算符来填充默认值var temp = targetValue || defaultValue;
如果targetValue为falsy,就会将defaultValue赋给temp变量。 - 关于
TypeError
的错误obj && obj.targetItem; // undefined
如果尝试从undefined
中取值就会得到一个TypeError
的错误,这时,我们可以使用&&
来避免。
对象(Objects)
JavaScript中的简单类型有:
- numbers
- strings
- booleans (true and false)
- null
- undefined
除了这些,其他的值都是对象。Numbers,strings,and booleans 因为它们有方法所以它们属于类对象(object-like),但它们都是不可变的。对象在JavaScript中是可变的键指向的集合(keyed collections)。在JavaScript中,数组,函数,正则包括对象自身都是对象。对象是属性集的容器,每个属性都有自己的键和值,属性的键包含空字符串在内的所有字符串,而属性的值则是除了undefined以外的任意值。
函数对象(Function Objects)
每个函数在创建时,会附带2个隐藏属性:函数的上下文和实现函数行为的代码。(JavaScript创建一个函数对象时,会给该对象设置一个“调用”属性,当JavaScript调用一个函数时,可理解为调用此函数的“调用”属性。)
调用一个函数时,除了接收声明时的形参,还会接收2个附加的参数:this
和arguments
。this
的指向取决于具体的调用模式,JavaScript中一共有4种调用模式。
- 方法调用模式(The Method Invocation Pattern)
当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用的时候,this被绑定到该对象。 - 函数调用模式(The Function Invocation Pattern)
var add = function ( a, b ) {
return a + b;
};
// The method invocation pattern, 'this' is bound to the object itself.
var myObject = {
value: 0,
increment: function ( inc) {
this. value += typeof inc === 'number' ? inc : 1;
}
};
myObject.increment(2);
console .log (myObject.value); //2
// The function invocation pattern
myObject.double = function () {
var that = this;
var helper = function () {
that .value = add( that.value, that.value) ;
}
helper ();
};
myObject.double();
console .log (myObject.value); // 4
- 构造器调用模式(The Constructor Invocation Pattern)
如果在一个函数前面带上 new 来调用,那么隐式地会创建一个链接到该函数的prototype成员的新对象,同时this会绑定到这个新对象上。
一个函数如果创建它的目的就是希望结合new前缀来调用,那么它就被成为构造器函数,按照约定,它们保存在以大写格式命名的变量里。 - Apply调用模式(The Apply Invocation Pattern)
apply方法让我们可以选择this的值,它接收2个参数,第一个是要绑定this的值,第二个是参数数组。
// The constructor invocation pattern
var Quo = function (string ) {
this. status = string ;
};
Quo. prototype.get_status = function () {
return this. status;
};
var myQuo = new Quo("confused");
console .log (myQuo.get_status ());
// The apply invocation pattern
var array = [3 , 4];
var sum = add.apply( null, array);
var statusObject = {
status: 'A-OK'
};
var status = Quo. prototype.get_status.apply( statusObject) ;
console .log (status) ;
糟粕的地方
- 作用域(Scope):JavaScript没有块级作用域,所以最好在每个函数的开头,声明你所需要的所有变量。
- 自动插入(Semicolon Insertion)
- 全局变量(Global Variables)
命名冲突,三种定义全局变量的方式:
- 函数之外的var语句;
- window对象直接添加属性;
- 隐式的全局变量,即直接使用未经声明的变量。
继承(Inheritance)
当对象被创建的时候,如果使用new关键字,就会调用默认的构造器,返回一个新的对象,并将this指向这个新的对象,但是如果你忘记使用new,或者漏了括号,则会污染全局变量。