以下内容摘自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,或者漏了括号,则会污染全局变量。