Js中的构造函数

  在写 JavaScript 的时候,经常可以看到 new Date() 这样的语法,这里 new 的就是构造函数,我们通过 function 可以定义,而箭头函数却不行。

是什么

构造函数,其实就是一种用来创建对象的函数

在 JavaScript 中,任何普通的 function 函数,只要你用 new 去调用它,它就被当成了构造函数。

1
2
3
4
5
function Dog(name) {
this.name = name;
}
const d = new Dog('旺财');
console.log(d); // Dog { name: '旺财' }

这里的 Dog 被当作构造函数使用,new Dog() 就相当于在“构造”一个新的 Dog 对象。

做了什么

new 关键字在背后其实做了几件事:

  1. 创建一个空对象:let obj = {};
  2. 把这个空对象的原型指向构造函数的 prototypeobj.__proto__ = Constructor.prototype;
  3. 执行构造函数,把 this 指向这个新对象:Constructor.call(obj)
  4. 如果构造函数返回了一个对象,就用这个对象;否则返回 obj

所以你写:

1
2
3
4
function Cat(name) {
this.name = name;
}
const c = new Cat('咪咪');

本质上 JS 干了:

1
2
3
4
let obj = {};
obj.__proto__ = Cat.prototype;
Cat.call(obj, '咪咪');
return obj;

为什么普通函数可以

普通的 function 在 JS 中是可以作为构造函数使用的原因是它内部有一个 [[Construct]] 方法(这是 JS 引擎里的内部实现),这个方法支持用 new 来调用。

1
2
3
function Apple() {}
console.log(typeof Apple); // 'function'
console.log(new Apple() instanceof Apple); // true

只要是具备 [[Construct]] 的函数,就能被 new

为什么箭头函数不行

我们来看个例子:

1
2
const Foo = () => {};
const f = new Foo(); // ❌ TypeError: Foo is not a constructor

箭头函数一旦用 new 调用,就直接报错:“不是构造函数”。

这是因为 箭头函数根本没有 [[Construct]] 方法

箭头函数它从一开始就不是用来“构造对象”的,它更像是一个轻量级的函数表达式,用来写一些简洁的回调或者小函数逻辑。

不仅如此,箭头函数还有这些“不能做”的事:

  • 没有自己的 this(它会捕获外层作用域的 this
  • 没有 prototype 属性
  • 不能用作构造函数(就是不能 new

所以写:

1
2
3
4
const Bar = () => {
this.value = 42;
};
new Bar(); // ❌ 报错

它连 this 都没有绑定到新对象上(捕获外层 this ),更别提用来构造了。

小结

特性 普通函数(function) 箭头函数(=>)
可以被 new 调用 ✅ 是构造函数 ❌ 报错
有自己的 this ❌(继承外层)
有 prototype 属性

所以说,当你想写一个“模板”来创建对象时,请用普通函数

箭头函数适合当“工具函数”或“回调函数”,别拿它来当构造器。

作者

Fu9Zhou

发布于

2025-04-10

许可协议