js-new
new 负责把实例、构造函数和原型接起来。
#type / concept
#status / growing
#resource / javascript
#resource / ecmascript
[!info] related notes
js-new
new 负责把实例、构造函数和原型接起来。
一句话定义
new 是 JavaScript 的运算符,用于调用构造函数创建实例对象。它在创建对象的同时,将该对象的 [[Prototype]] 内部槽指向构造函数的 prototype 属性,并绑定 this 到新创建的实例。
核心机制
new 做了什么
当执行 new Constructor() 时,JavaScript 引擎按顺序做4件事:
- 创建新对象 — 创建一个空对象
{} - 绑定原型 — 将对象的
[[Prototype]]指向构造函数的prototype - 绑定 this — 执行构造函数,
this指向新对象 - 返回对象 — 如果构造函数没有返回对象,则返回新对象;否则返回构造函数返回的对象
function Person(name) {
this.name = name
}
const p = new Person('Tom')
上述代码实际执行过程:
// 模拟 new 的内部步骤
function _new(constructor, ...args) {
// 1. 创建新对象
const obj = {}
// 2. 绑定原型
obj.__proto__ = constructor.prototype
// 3. 绑定 this 并执行
const result = constructor.apply(obj, args)
// 4. 返回结果(如果返回的是对象则用它,否则用 obj)
return result instanceof Object ? result : obj
}
new 和原型链的关系
new 的核心作用是把实例和构造函数的 prototype 连接起来:
function Foo() {}
Foo.prototype.say = function() { console.log('Hello') }
const f = new Foo()
f.say() // Hello
实例 f 本身没有 say 方法,但沿 f.__proto__(即 Foo.prototype)找到 say。
如果构造函数返回非对象
function Test() {
this.value = 1
return 2 // 返回原始类型
}
new Test().value // 1,返回 this
function Test() {
this.value = 1
return { value: 2 } // 返回对象
}
new Test().value // 2,返回自定义对象
最小例子
function Point(x, y) {
this.x = x
this.y = y
}
Point.prototype.toString = function() {
return `${this.x}, ${this.y}`
}
const p = new Point(1, 2)
console.log(p.x) // 1
console.log(p.toString()) // 1, 2
常见误解或边界
- new 必须配合构造函数使用 — 普通函数也能用
new,但没有实际意义 - new 不能和箭头函数一起用 — 箭头函数没有
[[Construct]],会报错 new后面必须加括号吗 — 有参数时必须加,无参数时可省略但不推荐
function Foo() {}
new Foo // 有效但不推荐
new Foo() // 推荐写法
new.target— 用于检测函数是否通过new调用
function Foo() {
console.log(new.target)
}
Foo() // undefined
new Foo() // Foo