箭头函数不绑定this

箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this

js
1
2
3
4
5
6
7
8
var id = 1
const obj = {
id: 2,
foo: () => {
console.log(this.id)
}
}
obj.foo()

答案输出是1

为什么呢?
因为箭头函数this指向等于定义时上层作用域中的this,所以是指向最外层window

再看一个例子

js
1
2
3
4
5
6
7
8
9
10
11
12
13
var id = 1
const obj = {
id: 2,
foo: function () {
setTimeout(() => {
console.log(this.id)
}, 1000)
}
}
const bar = obj.foo
bar() // 1

obj.foo.call(obj) // 2

为什么他们输出结果会不一致呢?

不是说箭头函数不会被外部影响改变,callapply方法对箭头函数无效吗?

接下来我们来一步步分析,为了方便大家理解,我将上述代码通过babel转换成es5来分析,如下

js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// es5
var id = 1;
var obj = {
id: 2,
foo: function foo() {
var _this = this;
setTimeout(function () {
console.log(_this.id);
}, 1000);
}
};
const bar = obj.foo
bar()
obj.foo.call(obj);

可以看出

箭头函数里面根本没有自己的this,而是引用的上层作用域中this

我们通过 call 来改变 this 指向改变是其父级的 this ,箭头函数里的 this 永远的指向其父级的作用域,而我们只是通过改变其父级的 this 指针,来达到箭头函数 this 的修改

箭头函数不绑定arguments,没有prototype原型对象

js
1
2
3
4
const f1 = function (val) { console.log(val) }
const f2 = (val) => console.log(val)
console.dir(f1)
console.dir(f2)

image.png
可以发现箭头函数没有argumentsprototype原型对象

箭头函数不绑定arguments,取而代之用rest参数…解决

js
1
2
3
4
const f = (...args) => {
console.log(args)
}
f(1,2,3) // [1,2,3]

箭头函数是匿名函数,不能作为构造函数,不能使用new

我们先来看看new的原理

js
1
2
3
4
5
6
7
8
9
// new的原理
function create(Con, ...args) {
let obj = {}
obj.__proto__ = Con.prototype
let result = Con.apply(obj, args)
return result instanceof Object ? result : obj
}


通过上面已知的信息,箭头函数没有prototype,所以无法使实例的__proto__指向其构造函数的原型