JavaScript中this指向的修改

已经介绍过JavaScript中this指向的原理,今天介绍一下this指向的几个复杂解析,和如何改变this的指向。

关于this的指向,有几个点需要注意:

  • this指向的,只能是对象。
  • this指向谁,取决于函数的执行环境,而不是在创建时就决定了。
  • 匿名函数的执行环境具有全局性。
  • 对于普通函数调用,我们通常把this绑定为null

一、this问题

举个?:

function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}

const xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};

xiaoming.age(); // 29, 正常结果
getAge(); // NaN

this指向函数被调用的对象(执行环境)。
由于这是一个巨大的设计错误,ECMA规定,在strict模式下让函数的this指向undefined
上面?在strict模式下调用getAge(),会得到一个错误。这个决定只是让错误及时暴露出来,并没有解决this应该指向的正确位置。

有时因为编写闭包方式不同,也会导致this指向问题,而且不易被发现。
再来一个?:

const name = 'this window'
const obj = {
    name : 'my object',

    getName : function(){
        function getNameFunc(){
            return this.name
        }
        return getNameFunc()
    }
}
obj.getName()  //undefined

getNameFunc在匿名函数中执行,匿名函数的执行环境具有全局性,this又指向window了!

二、改变this的指向

  • 定义that变量捕获this

修复第二个?:

const name = 'this window'
const obj = {
    name : 'my object',

    getName : function(){
        const that = this;  //that捕获this为对象obj
        function getNameFunc(){
            return that.name
        }
        return getNameFunc()
    }
}
obj.getName()  //my object

我们还可以调用函数本身的applycallbind来指定函数的this指向哪个对象。

  • apply

apply接收两个参数,第一个参数是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。
修复第一个?:

function getAge() {
    const y = new Date().getFullYear();
    return y - this.birth;
}

const xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};

xiaoming.age(); // 29, 正常结果
getAge.apply(xiaoming,[]); // 29,正常结果
  • call

callapply类似,唯一的区别是:
apply()把参数打包成Array传入,而call()把参数按顺序传入。

  • bind

函数的bind指定一个对象,将this绑定到这个对象上。
bind修复第一个?:

function getAge() {
    const y = new Date().getFullYear();
    return y - this.birth;
}

const xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};


xiaoming.age(); // 29, 正常结果
getAge.bind(xiaoming)() //29,正常结果

三、箭头函数(ES6)

箭头函数解决了this指向混乱问题。
this对象的指向是可变的,但在箭头函数中它是固定的。
箭头函数有一个重要的特性:
函数体内的this对象就是定义时所在的对象,而不是使用时所在的对象
解释一下底层原因:
this指针的固定化并不是箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this,正是因为它没有this,所以不能用作构造函数。
修复第二个?:

const name = 'this window'
const obj = {
    name : 'my object',

    getName : function(){
        const getNameFunc = ()=> {
            return this.name
        }
        return getNameFunc()
    }
}
obj.getName()  //my object

转载请标明来源:sherrybaby的博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值