函数中this的取值,是在函数调用的预处理时确定的,而不是函数定义时确定的。因为this的取值是执行上下文环境的一部分,而每次调用函数才会对函数中的代码段做一次预处理,进而产生一个新的执行上下文环境。

this的取值,分四种情况:

情况1.构造函数

所谓构造函数就是用来通过“new”实例化对象的函数。严格来说,所有的函数都可以new一个对象,但是有些函数的定义就是为了用来实例化对象,而有些知识当做普通函数来用。构造函数的首字母通常大写,以区别于普通函数。例如:Object、Array、Function等。

function Person() {
    this.fName = "Jerry";
    this.lName = "Zhang";
    
    console.log(this);      //Person {fName: "Jerry", lName: "Zhang"}
}

var person = new Person();

console.log(person.fName);  //Jerry
console.log(person.lName);  //Zhang

结论:构造函数中的this代表即将new出来的那个对象。

但,如果构造函数作为普通函数直接被调用时:

function Person() {
    this.fName = "Jerry";
    this.lName = "Zhang";
    
    console.log(this);      
}

Person();

打印结果为:

clipboard.png

结论:构造函数作为普通函数被调用时,其中的this代表window。

如果this在构造函数的prototype中:

function Fn() {

this.fName = "Jerry";
this.lName = "Zhang";

}

Fn.prototype.getFullName = function() {

console.log(this.fName + " " + this.lName);

}

var f1 = new Fn();
f1.getFullName(); //Jerry Zhang

结论:构造函数的原型中的this代表当前对象。不仅仅是构造函数的prototype,即便是在整个原型链中,this代表的也都是当前对象的值。

情况2.函数作为对象的一个属性

如果函数是对象的一个属性,且作为对象的一个属性被调用时:

var obj = {
    x: 10,
    fn: function() {
        console.log(this);      //见下图
        console.log(this.x);    //10
    }
};

obj.fn();

clipboard.png

结论:函数是对象的一个属性,且作为对象的一个属性被调用时,函数中的this代表该对象

但,如果该函数不作为对象的一个属性,而是作为普通函数被调用时:

var obj = {
    x: 10,
    fn: function() {
        console.log(this);      //见下图
        console.log(this.x);    //undefined
    }
};

var fn1 = obj.fn;
fn1();

clipboard.png

结论:如果函数是对象的一个属性,但作为普通函数被调用时,其中的this代表window。

情况3:函数用call或者apply调用

call、apply的区别:

fn.call(obj, a, b, c);
fn.apply(obj, [a, b, c]);
详见:[http://www.cnblogs.com/xljzlw/p/3775162.html][2]

var obj = {
    x: 10
};

var fn = function() {
    console.log(this);      //Object {x: 10}
    console.log(this.x);    //10
};

fn.call(obj);

结论:函数被call或apply调用时,函数中的this代表传入的那个参数对象。

情况4:全局 & 调用普通函数

console.log(this === window);   //true

结论:全局环境下,this永远代表window。

var x = 20; 
var fn = function () {
    console.log(this);      //见下图
    console.log(this.x);    //20
}

fn();

clipboard.png

结论:普通函数调用时,其中的this代表window。

还有一种特殊的普通函数:

var obj = {
    x: 10,
    fn: function() {
        function f() {
            console.log(this);      //见下图
            console.log(this.x);    //undefined
        }
        f();
    }
};

obj.fn();

clipboard.png

结论:对象的属性函数中定义且调用的函数,仍然是普通函数,其中的this代表window。

总结:

  1. 构造函数当做构造函数使用时,其中的this代表其实例化出来的对象;构造函数当做普通函数直接被调用时,其中的this代表window。

  2. 原型链中的this代表的是当前对象。

  3. 函数是对象的一个属性时,若作为对象的属性被调用时,其中的this代表该对象;若作为普通函数被调用时,其中的this代表window。

  4. 函数被call或apply调用时,其中的this代表传入的那个参数对象。

  5. 全局环境下,this永远代表window。

  6. 普通函数调用时,其中的this代表window。

  7. 对象的属性函数中定义且调用的函数,仍然是普通函数,其中的this代表window。


Jerry
226 声望32 粉丝