跳到主要内容

README

普通函数和箭头函数的区别

没有 this

箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值。

这就意味着如果箭头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的 this。

没有 arguments

箭头函数可以访问外围函数的 arguments 对象:

function constant() {
return () => arguments[0]
}

var result = constant(1);
console.log(result()); // 1

不能通过 new 关键字调用

JavaScript 函数有两个内部方法:[[Call]] 和 [[Construct]]。 当通过 new 调用函数时,执行 [[Construct]] 方法,创建一个实例对象,然后再执行函数体,将 this 绑定到实例上。当直接调用的时候,执行 [[Call]] 方法,直接执行函数体。 箭头函数并没有 [[Construct]] 方法,不能被用作构造函数,如果通过 new 的方式调用,会报错。

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

没有原型 prototype

由于不能使用 new 调用箭头函数,所以也没有构建原型的需求,于是箭头函数也不存在 prototype 这个属性。

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

没有 super

连原型都没有,自然也不能通过 super 来访问原型的属性,所以箭头函数也是没有 super 的

没有 new.target

new.target是ES6新引入的属性,普通函数如果通过new调用,new.target会返回该函数的引用。 箭头函数的this指向普通函数,它的new.target就是指向该普通函数的引用。

new bb();
function bb() {
let a = () => {
console.log(new.target); // 指向函数bb:function bb(){...}而不是a函数
};
a();
}

箭头函数的继承性

this、arguments、new.target、super 这些值由外围最近一层非箭头函数决定。

被继承的普通函数的this等这些属性的指向改变,箭头函数的指向会跟着改变

注意点

箭头函数外层没有普通函数

严格模式和非严格模式下它的this都会指向window(全局对象)

对象嵌套

对象嵌套的话没有发生作用域链的嵌套,不能方法在对象里嵌套多少层this总是指向对象外面的函数或者全局

var obj = {
i: 10,
b: () => console.log(this.i, this),
c: {
d: () => console.log(this.i, this),
}
}
obj.b();
// Window
obj.c.d();
// 虽然是链式调用但是是对象,Window

不能直接修改箭头函数的this指向

let fnObj = { msg: '尝试直接修改箭头函数的this指向' };
function foo() {
let a = ()=>{
console.log(this)
}
a.call(fnObj); // this指向是全局,无法绑定this
}
foo()