理解this指针的用法

this指针的用法

常规用法

对this的理解是,指向 直接操作这个量的函数(或变量、对象)所属的对象 的指针,也就是指向爹的爹,指向爷爷。通过几个例子了解一下this的常见用法:

var name = 1;
var util = {
    name: 2,
    myName: this.name
    getName: function(){
        return this.name;
    },
    sub: {
        name: 3,
        getName: function(){
            console.log(this);
            return this.name
        }
    }
}

常规的this使用及结果

console.log(util.myName);  //1 this指向window
console.log(util.getName()); // 2 this指向util
console.log(util.sub.getName()); // 3 this指向sub

如果是下列情况

var a = util.getName;
console.log(a()); //结果为1

解释:a=util.getName;使得 a 成为一个全局函数,即

a=function(){return this.name;} 

此时的this指向 window ,得到 window.name
另一种情况:

var b = util.sub;
console.log(b.getName()); // 3 

解释:同理上个例子, b 是一个全局对象,

b = {
    name: 3,
    getName: function(){
        console.log(this);
        return this.name
    }

b.getName() 中的this即指向getName()所属的对象 b ,得到 b.name

还有,如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。例子如下:

function getName(){  
    this.name = 1;  
    return {}; // 返回对象
}
var a = new getName;  
console.log(a.name); //undefined

function getName(){  
    this.name = 1;  
    return 2; // 返回非对象
}
var d = new getName;  
console.log(d.name); //1

匿名函数中的this

在非严格模式下,匿名函数的执行环境具有全局性,因此其this对象指向window.
例子如下:

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = function () {
            return new Date().getFullYear() - this.birth; // this指向window(非严格模式)或undefined(严格模式)
        };
        return fn();
    }
};

要想获得预期的结果,可以使用以下hack写法,加一行 var that = this;

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = function () {
            var that = this;
            return new Date().getFullYear() - that.birth; // that指向obj
        };
        return fn();
    }
};

箭头函数中的this

箭头函数和匿名函数的区别:箭头函数内部的this是词法作用域,由上下文确定。
回顾前面的例子,由于JavaScript函数对this绑定的错误处理,无法得到预期的结果。
现在,箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
        return fn();
    }
};
obj.getAge(); // 25

如果使用箭头函数,以前的那种hack写法:

var that = this;

就不再需要了。

由于this在箭头函数中已经按照词法作用域绑定了,所以,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略:

var obj = {
    birth: 1990,
    getAge: function (year) {
        var b = this.birth; // 1990
        var fn = (y) => y - this.birth; // this.birth仍是1990
        return fn.call({birth:2000}, year);
    }
};
obj.getAge(2015); // 25
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章