1、箭头函数为什么不能被
new?2、箭头函数的
this绑定为什么无法被修改?3、有什么办法可以修改箭头函数的
this指向绑定?
1.箭头函数没有构造函数
来看下面这个例子
new (() => {})
Uncaught TypeError: (intermediate value) is not a constructor
at <anonymous>:1:1
在
JS中,构造函数只是使用new操作符时被调用的普通函数,他们不属于某个类,也不会实例化一个类。
而箭头函数没有name属性,也并非通过function等方式定义,而new操作符在构造在执行构造的时候,在编译过程,词法解析中会将后面的函数作为构造函数使用,而箭头函数 () = >{} 会被词法解析识别,当做大型块作用域来处理(所有代码在为编译阶段都是一堆字符串)
下面是new的简单实现:
function create () {
// 1.创建一个空对象, new Object方式创建的比较纯净,只有Object.prototype继承
let obj = new Object();
// 2.new 后面的构造函数会作为第一个参数传递进new函数,通过获取arguments第一次参数方式获取
const Con = [].shift.call(arguments);
// 3.新对象的原型指向构造函数的原型
obj.__proto__ = Con.prototype;
// 4.指向构造函数,如果构造函数执行后有返回值,则返回函数执行后的返回值,如果没有则以当前新对象obj作为返回值
var ret = Con.apply(obj, arguments);
return ret instanceof Object ? ret : obj;
}
2.箭头函数根据外层作用域(词法作用域)来决定this,而不是本身的this
以下是[木易杨](https://muyiy.cn/blog/3/3.2.html#%E9%A2%98%E7%9B%AE1)大佬关于箭头函数this指向的总结:
-
箭头函数不绑定this,箭头函数中的this相当于普通变量。
-
箭头函数的this寻值行为与普通变量相同,在作用域中逐级寻找。
-
箭头函数的this无法通过bind,call,apply来直接修改(可以间接修改)。
-
改变作用域中this的指向可以改变箭头函数的this。
结合以上,如果把箭头函数产生的作用域当成块级作用域,是否能帮助我们快速的理解上面结论呢?
3.箭头函数可以通过修改上级作用域的方式来间接修改。
上面结论说过,箭头函数的this寻值行为与普通变量相同,在作用域中逐级寻找,那么只要通过修改上级作用域的方式就可以间接修改了。
var person1 = { name: 'person1',
show: function () {
return () => console.log(this.name)
}
}
var person2 = { name: 'person2' }
person1.show().call(person2) // person1 person1.show.call(person2)() // person2
写文章的目的目前主要是作为学习的总结,通过输出的方式来加强自己对知识点的理解,路过的掘友,鄙人写的不好的地方请轻喷,如果能指出需要修改的地方那就再好不过了。要是懒得吐槽,那就当乐子