JavaScript不同函数调用模式下this关键字的指向
发布于 1天前 作者 dandananddada 85 次浏览 来自 分享

函数调用的四种模式

  1. 方法调用模式
  2. 函数调用模式
  3. 构造器调用模式
  4. Apply调用模式

方法调用模式

函数在作为一个对象的属性被调用的时候就属于方法调用模式。这个时候this是指向调用这个函数的对象的。

var myObject = {    
    value: 0,
    increnment: function(){
        this.value += 1;
    }
}
myObject.increnment();
console.log(myObject.value);        //=>1

上述例子中this.value就相当于myObject.value

函数调用模式

当一个函数直接调用时就是函数调用模式。这时候this指向的是全局对象。

var value = 1;
function increnment(){
    this.value += 1;
}

var myObject = { 
    value: 0,
    callIncrement: function(){
        increnment()
    }
}
myObject.callIncrement();
console.log(value);                 //=>2
console.log(myObject.value);        //=>0

这时候执行到increment方法时,因为this指向的是全局对象,所以作增量的是全局的value而不是myObject.value

这里规范说明下:根据ECMAScript3和非严格的ECMAScript5对函数调用的规定,调用上下文(this的值)是全局对象,然而,在严格模式下,调用上下文则是undefined。[摘自JavaScript权威指南(第六版)8.2.1 函数调用]

构造器调用模式

通过new关键字调用的函数,属于构造器调用模式,这时this指向的是这个新对象。

var o = {
    value : 0,
    ConstructorFunction: function(value){
        this.value = value;
        return this.value;
    }
}
var b = new o.ConstructorFunction(2);
console.log(o.value);           //=>0
console.log(b.value);           //=>2

注意这里使用了new关键字,因此这个时候this指向的不再是方法调用模式下的调用对象,而是构造器返回的对象。所以这里的this.value = value相当于b.value = value

同样规范的说明:然而如果构造函数使用return语句显示的返回一个对象,那么调用表达式的值就是这个对象。如果构造函数使用return语句但没有返回值,或者返回一个原始值,那么将忽略返回值,同时使用这个新对象作为调用结果。[摘自JavaScript权威指南(第六版)8.2.3 构造函数调用]

也就是说构造函数默认没有返回值时返回新对象,如果有使用return返回值,则遵守如上约定。

Apply调用模式

因为函数本身也是对象,所以函数也可以拥有方法。在使用Apply方法调用函数时,this指向的是传递给apply方法中的第一个参数。

var obj = {
    value: 0,
    add: function(value){
        this.value += value;
    }
}
var myObj = {   value: 1    };
function getValue(value){
     this.value += value;
}
obj.add.apply(myObj,[3]);
console.log(obj.value);         //=>0
console.log(myObj.value);       //=>4

这里apply方法第一个参数为this指向对象,第二个参数为调用函数的参数(通过数组方式传递)。因为apply方法使this指向了myObj,所以this.value+=value相当于myObject.value+=value

说明

例子代码修改自《JavaScript语言精髓》26-30页。

回到顶部