面试题:为什么箭头函数不能当构造函数

212 阅读2分钟

箭头函数

const ArrowFun = ()=>{}
console.dir(ArrowFun)

image.png

const arrowfun = new ArrowFun()

image.png

构造函数

const Fun = function(){}
console.dir(Fun)

image.png

const fun = new Fun()
console.log(fun)

image.png

分析

  • 显然易见的就是箭头函数在new时会报错 TypeError: ArrowFun is not a constructor
  • 对比箭头函数与构造函数,箭头函数缺少了很多东西caller,arguments,prototype等

为什么会报is not a constructor

深入理解ES6

深入理解ES6这本中箭头函数篇章中提到一下内容:

image.png

中文翻译内容如下:

image.png

从深入理解ES6这本书可以看出由于没有[[Construct]]方法,所以箭头函数不是构造函数。使用new 调用会报错,也就是is not a constructor

ECMAScript 2015 语言规范

ECMAScript 2015 语言规范提到以下内容:

image.png

简单翻译一下:

1.创建 ECMAScript 原生对象 obj
2.给 obj 设置原生对象的内部属性;
3.设置 obj 的内部属性 [[Class]]Object
4.设置 obj 的内部属性 [[Extensible]]true
5.将 proto 的值设置为 Fprototype 属性值;
6.如果 proto 是对象类型,则设置 obj 的内部属性 [[Prototype]] 值为 proto
7.如果 proto 是不对象类型,则设置 obj 的内部属性 [[Prototype]] 值为内建构造函数,如果改成非对象类型,obj[[Prototype]] 就指向 Object 的原型对象)
8.调用函数 F,将其返回值赋给 result;其中,F 执行时的实参为传递给 [[Construct]](即 F 本身) 的参数,F 内部 this 指向 obj
9.如果 result 是 Object 类型,返回 result
10.如果 F 返回的不是对象类型则返回创建的对象 obj

简单实现myNew

function myNew(fn, ...args) {
  const obj = {};
  obj.__proto__ = fn.prototype;
  const result = fn.apply(obj, args);
  return typeof result === "object" ? result : obj;
}

总结

new执行过程

1)创建新对象
3)执行函数,执行过程中内部 this 指向新创建的对象
4)如果结果对象类型数据,则,返回该数据,执行结束;不然返回新创建的对象。

箭头函数的特殊性

  • 没有[[Construct]]内置方法,也就是说箭头函数不是构造函数不能通过new来创建对象

彩蛋

箭头函数设计想法