Javascript语言精粹
检索
检索一个并不存在的成员属性的值,将返回undefined
flight.status //undefined
|| 运算符可以用来填充默认值
var status = flight.status || "unknown";
尝试从undefined的成员属性中取值,将会报错TypeError。这时可以通过&&运算符来避免错误
flight.equipment //undefined flight.equipment.model //Throw "TypeError" flight.equipment && flight.equipment.model //undefined
引用
对象通过引用来传递。他们永远不会被复制。
var a = {}, b = {}, c = {}; //a,b,c每个都引用一个不同的空对象
var a = b = c = {}; //a,b,c都引用同一个空对象
原型
如果我们尝试去获取对象的某个属性值,但该对象并没有此属性名,那么Javascript会试着从原型对象中获取属性值。
如果哪个原型对象也没有该属性,那么再从它的原型中查找。以此类推,直到最后到达终点 Object.prototype。
如果想要的属性完全不存在于原型链中,那么结果就是undefined值。
这个过程称为委托。
反射
//反射机制指的是程序在运行时能够获取自身的信息。
//如:一个对象能够在运行时知道自己有哪些方法和属性。
检查对象并确定对象有什么属性是很容易的事情。
typeof操作符对确定属性的类型很有帮助:
typeof flight.number //'number' typeof flight.status //'string' typeof flight.manifest //'undefined'
注意原型链中的任意属性都会产生值:
typeof flight.toString //'function' typeof flight.constructor //'function'
有两种方法去处理这些不需要的属性:
第一个是检查并丢弃值为函数的属性。
第二种是使用hasOwnProperty方法:
如果对象拥有独有的属性,它将返回true,hasOwnProperty方法不会检查原型链。
flight.hasOwnProperty('number'); //true
flight.hasOwnProperty('constructor'); //false
枚举
for in 语句可以枚举所有的属性——包括函数和原型中的属性。最好用for代替之。
以特定顺序枚举对象的属性:
var i;
var properties = [
'first-name',
'middle-name',
'last-name',
'profession'
];
for(i=0; i<properties.length; i++){
document.writeln(properties[i] + ":" +
another_stooge[properties[i]]);
}
函数的调用
调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数。
函数总会附加两个参数:this 和 arguments。
this的值取决于调用模式:
- 方法调用模式
- 函数调用模式
- 构造器调用模式
- apply调用模式
当实际参数的个数和形式参数的个数不匹配时:
如果实际参数值过少,缺失的值会被替换为undefined。
方法调用模式
当一个函数被保存为对象的一个属性时,我们称它为一个方法。此时,this被绑定到该对象。
函数调用模式
当一个函数并非对象的属性时,那么它就是被当做一个函数来调用。此时,this被绑定到全局对象。(这是语言设计上的一个错误)
解决方案:使用that
构造器调用模式
如果一个前面带上new来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象。同时,this被绑定到新对象上。
var myQuo = new Quo("confused");
按照约定,它们保存在以大写命名的变量里。(我们不推荐这种调用方式)
apply调用模式
函数可以拥有方法。
apply方法接收两个参数:1个是要绑定给this的值。第2个是一个参数数组。
var arr = [3, 4];
var sum = add.apply(null, arr);
var statusObject = {
status: "A-OK"
};
// 我们可以在statusObject对象上调用get_status方法
// 尽管statusObject对象并没有该方法
var status = Quo.prototype.get_status.apply(statusObject);
参数
函数被调用时,会得到一个免费的参数——arguments数组。
但arguments并不是一个真正的数组,它拥有一个length属性,但没有任何数组方法。
返回
当一个函数被调用时,它从第一个语句开始执行,并在遇到 } 时结束。
然后把控制权交还给调用该函数的程序。
return 可以使函数提前返回,不再执行余下语句。
一个函数总会返回一个值,如果没有指定返回值,则返回undefined。
如果函数调用时,在前面加上了new前缀,且返回值不是一个对象,则返回该新对象(this)
扩充类型的功能
我们可以通过Object.prototype添加方法。同样,可以对函数,数组,字符串,数字,正则表达式,布尔值添加。
举例来说,可以通过给 Function.prototype 增加方法来使得该方法对所有函数可用。
Function.prototype.method = function(name, func){
this.prototype[name] = func;
return this;
};
给Function.prototype增加一个method方法,我们下次给对象添加方法的时候,就不必键入prototype这几个字符了。
javascript中没有专门的整数类型,但有事我们需要提取数字中的整数部分。
Number.method('integer', function(){
// 根据正负来使用Math.ceil或者Math.floor
return Math[this < 0 ? 'ceil' : 'floor'](this);
});
基本类型的原型是公用结构,所以在类库混用时务必小心。
保险做法是在确定没有该方法时才添加它。
Function.prototype.method = function(name, func){
if(!this.prototype[name]){
this.prototype[name] = func;
}
return this;
};
浙公网安备 33010602011771号