Js中的构造函数
在写 JavaScript 的时候,经常可以看到 new Date() 这样的语法,这里 new 的就是构造函数,我们通过 function 可以定义,而箭头函数却不行。
是什么
构造函数,其实就是一种用来创建对象的函数。
在 JavaScript 中,任何普通的 function 函数,只要你用 new 去调用它,它就被当成了构造函数。
1 | function Dog(name) { |
这里的 Dog 被当作构造函数使用,new Dog() 就相当于在“构造”一个新的 Dog 对象。
做了什么
new 关键字在背后其实做了几件事:
- 创建一个空对象:
let obj = {}; - 把这个空对象的原型指向构造函数的
prototype:obj.__proto__ = Constructor.prototype; - 执行构造函数,把
this指向这个新对象:Constructor.call(obj) - 如果构造函数返回了一个对象,就用这个对象;否则返回
obj
所以你写:
1 | function Cat(name) { |
本质上 JS 干了:
1 | let obj = {}; |
为什么普通函数可以
普通的 function 在 JS 中是可以作为构造函数使用的原因是它内部有一个 [[Construct]] 方法(这是 JS 引擎里的内部实现),这个方法支持用 new 来调用。
1 | function Apple() {} |
只要是具备 [[Construct]] 的函数,就能被 new。
为什么箭头函数不行
我们来看个例子:
1 | const Foo = () => {}; |
箭头函数一旦用 new 调用,就直接报错:“不是构造函数”。
这是因为 箭头函数根本没有 [[Construct]] 方法。
箭头函数它从一开始就不是用来“构造对象”的,它更像是一个轻量级的函数表达式,用来写一些简洁的回调或者小函数逻辑。
不仅如此,箭头函数还有这些“不能做”的事:
- 没有自己的
this(它会捕获外层作用域的this) - 没有
prototype属性 - 不能用作构造函数(就是不能
new)
所以写:
1 | const Bar = () => { |
它连 this 都没有绑定到新对象上(捕获外层 this ),更别提用来构造了。
小结
| 特性 | 普通函数(function) | 箭头函数(=>) |
|---|---|---|
| 可以被 new 调用 | ✅ 是构造函数 | ❌ 报错 |
| 有自己的 this | ✅ | ❌(继承外层) |
| 有 prototype 属性 | ✅ | ❌ |
所以说,当你想写一个“模板”来创建对象时,请用普通函数;
箭头函数适合当“工具函数”或“回调函数”,别拿它来当构造器。