ES6箭头函数的作用域this指向

作用域

这个箭头函数的作用域和其他函数有一些不同,如果不是严格模式,this关键字就是指向window,严格模式就是undefined,在构造函数里的this指向的是当前对象实例,如果this在一个对象的函数内则this指向的是这个对象,this有可能指向的是一个dom元素,例如当我们添加事件监听函数时,可能这个this的指向不是很直接,其实this(不止是this变量)变量的指向是根据一个规则来判断的:作用域流。下面我将演示this在事件监听函数和在对象函数内出现的情况:

在事件监听函数中:

document.body.addEventListener('click', function(evt){    console.log(this); // the HTMLBodyElement itself});

在构造函数里:

function Person () {    let fullName = null;    this.getName = function () {        return fullName;
    };    this.setName = function (name) {
        fullName = name;        return this;
    };
}let jon = new Person();
jon.setName("Jon Doe");console.log(jon.getName()); // "Jon Doe"

在这个例子中,如果我们让Person.setName函数返回Person对象本身,我们就可以这样用:

jon.setName("Jon Doe")
   .getName(); // "Jon Doe"
在一个对象里:

let obj = {
    foo: "bar",
    getIt: function () {        return this.foo;
    }
};console.log( obj.getIt() ); // "bar"

但是当执行流(比如使用了setTimeout)和作用域变了的时候,this也会变。

function Student(data){    this.name = data.name || "Jon Doe";    this.age = data.age>=0 ? data.age : -1;    this.getInfo = function () {        return this.name + ", " + this.age;
    };    this.sayHi = function () {        window.setTimeout( function () {            console.log( this );
        }, 100 );
    }

}let mary = new Student({
    name: "Mary Lou",
    age: 13});console.log( mary.getInfo() ); // "Mary Lou, 13"mary.sayHi();// window

当setTimeout函数改变了执行流的情况时,this的指向会变成全局对象,或者是在严格模式下就是undefine,这样在setTimeout函数里面我们使用其他的变量去指向this对象,比如self,that,当然不管你用什么变量,你首先应该在setTimeout访问之前,给self,that赋值,或者使用bind方法不然这些变量就是undefined。

这是后就是箭头函数登场的时候了,它可以保持作用域,this的指向就不会变了。

让我们看下上文起先的例子,在这里我们使用箭头函数:

function Student(data){    this.name = data.name || "Jon Doe";    this.age = data.age>=0 ? data.age : -1;    this.getInfo = function () {        return this.name + ", " + this.age;
    };    this.sayHi = function () {        window.setTimeout( ()=>{ 
            // the only difference is here
            console.log( this );
        }, 100 );
    }

}let mary = new Student({
    name: "Mary Lou",
    age: 13});console.log( mary.getInfo() ); // "Mary Lou, 13"mary.sayHi();// Object { name: "Mary Lou", age: 13, ... }

在sayHi函数中,我们使用了箭头函数,当前作用域是在student对象的一个方法中,箭头函数生成的临时函数的作用域也就是student对象的sayHi函数的作用域。所以即使我们在setTimeout调用了箭头函数生成的临时函数,这个临时函数中的this也是正确的指向。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值