JavaScript的语法要点 3 - Calling Context
上一篇讲了JavaScript的Scope Chain - 每一个函数都有一个scope chain与之关联,scope chain上有第一个对象维护着本地变量作为其属性。另外我们在JavaScript函数中经常看到this,那么this是不是scope chain上的第一个对象呢?答案是否。Scope chain是scope chain,this则是calling context,两者没有什么关系。
正如JavaScript书籍中所讲的:除了参数之外,函数调用时会有另外一个值 - 称之为invocation context (调用上下文) - 这个值用this关键字来表示。
我们到知道JavaScript函数有四种调用方式: 普通调用、作为对象方法调用、作为构造函数调用、被call/apply调用。这些调用方式的主要区别就在于它的invocation context有所不同。
函数作为一个普通函数调用的话,其invocation context是全局对象或undefined,这个JavaScript的标准中没有严格规定。
函数作为一个对象方法调用的话,其invocation context是对象,比如:
o.m = f;
o.m(); // 当f作为o的对象方法调用时,f函数体内的this指的是o。
需要注意的是,this关键字不是普通变量,它并没有作用域,因此内嵌函数的this是全局对象或undefined,比如:
var o = {
m: function(){
var self = this;
console.log(this == o); // 输出为true
f();
function f(){
console.log (this == o); //输出为false
console.log (self == 0); // 输出为true
}
}
}
函数作为构造函数调用也十分重要,它是面向对象设计的基础:当一个函数前面有一个new关键字时,它就是构造调用。构造调用会创建一个新的空对象,对象从函数的prototype属性继承。我们称这个函数时构造函数,构造函数的invocation context是新创建的空对象。一般情况下,构造函数没必要使用return关键字,因为函数作为构造函数调用时,会隐含的返回所创建的新对象;然而如果此函数使用了return并返回一个对象时,那么新创建的对象就会被这个返回的对象代替;如果return的是值类型,那么返回值会被忽略,而真正的新建对象会被返回。