【前端工程师手册】this拾遗之关于箭头函数的种种

以前总结了this的一些常见绑定状况(【前端工程师手册】JavaScript之this的笔记),可是还有一些没有说到,今天继续学习一下。前端

es6箭头函数

先说结论:箭头函数没有本身的this,它是根据外层(函数或者全局,后面会说到箭头函数做为某个对象的方法时的状况)做用域来决定this,箭头函数能够像 bind(..) 同样确保函数的 this 被绑定到指定对象,也就是说它在运行中不会丢失this,它的this是在声明箭头函数时就决定了。es6

一个例子

var name = 'out'
function  test(){
    this.name = 'in';
    setTimeout(function(){
        console.log(this.name)
    },1000)
}
new test() // 1秒后打印'out'

上面这个是es5中常见的this问题,计时器1s后运行匿名函数,this已经丢失了,因而默认绑定到了window上。
以前的经典处理方法是:segmentfault

var name = 'out'
function  test(){
    this.name = 'in';
    var self = this;
    setTimeout(function(){
        console.log(self.name)
    },1000)
}
new test() // 1秒后打印'in'

显式的使用self来保存住正确的this,防止this丢失。
其实这些均可以使用箭头函数来实现:前端工程师

var name = 'out'
function  test(){
    this.name = 'in';
    setTimeout(() => {
        console.log(this.name)
    },1000)
}
new test() // 1秒后打印'in'

在上面的代码片断中,箭头函数内部的this在声明期间就绑定为外层函数的this,且在运行过程当中不会被修改。app

不能当作构造函数

var Agumon = () => {  this.name = 'agumon' }

var agumon = new Agumon() // Uncaught TypeError: Agumon is not a constructor

使用箭头函数去当作构造函数来new对象会直接报错,不过这个也好理解,由于箭头函数并无本身的this,new操做中有用到this的步骤它搞不定。函数

call或apply调用无效

function foo() {
// 返回一个箭头函数
    return (a) => {
        console.log( this.a ); 
    };    
}
var obj1 = {
    a:2
};
var obj2 = { a:3};
var bar = foo.call( obj1 );
bar.call( obj2 ); // 2, 不是3

上面的代码片断显式的使用call来想把foodethis绑定到obj1,然而并不奏效,由于箭头函数的this并不会在运行时再被改变。学习

没有prototype

var Foo = () => {};
console.log(Foo.prototype); // undefined

箭头函数是没有原型的this

不适用于做为对象的方法

var obj = {
    i: 10,
    b: () => console.log(this.i, this),
    c: function() {
        console.log( this.i, this)
    }
}
obj.b(); 
// undefined
obj.c(); 
// 10, Object {...}

刚刚说了根据外层做用域来决定this,上面代码片断中的对象obj还不足以生成做用域,再往上就是全局做用域了,因此this被绑定为window。
参考资料:
MDN-箭头函数
《你不知道的JavaScript-上卷》es5

相关文章
相关标签/搜索