在JavaScript 中,new
操作符用于创建一个由构造函数生成的用户定义的对象实例。当使用 new
操作符调用一个构造函数时,它执行了以下几步操作:
1. 创建一个新的对象
2. 设置原型链
将新创建的对象的原型(__proto__
)设置为构造函数的 prototype
属性。
3. 绑定 this
构造函数内部的 this
被赋值为这个新对象(即 this
指向新对象)。
4. 执行构造函数内部的代码
5. 处理返回值
如果构造函数返回非空对象(包括有对象、数组、函数),则返回该对象;否则,返回刚创建的新对象。
示例代码
以下是一个简单的例子,展示了 new
操作符的工作机制:
构造函数不返回值(相当于返回 undefined
)
// 定义一个构造函数
function Person(name, age) {
// this 指向新创建的对象
this.name = name;
this.age = age;
// 这里不返回任何值
}
// 使用 new 操作符创建 Person 的实例
const person1 = new Person('qdxs', 18);
console.log(person1.name); // 输出: qdxs
console.log(person1.age); // 输出: 18
console.log(person1 instanceof Person); // 输出: true
console.log(person1.__proto__ === Person.prototype); // 输出: true
构造函数返回 null
// 定义一个构造函数
function Person(name, age) {
// this 指向新创建的对象
this.name = name;
this.age = age;
// 这里返回 null
return null
}
// 使用 new 操作符创建 Person 的实例
const person1 = new Person('qdxs', 18);
console.log(person1.name); // 输出: qdxs
console.log(person1.age); // 输出: 18
console.log(person1 instanceof Person); // 输出: true
console.log(person1.__proto__ === Person.prototype); // 输出: true
构造函数返回 number
// 定义一个构造函数
function Person(name, age) {
// this 指向新创建的对象
this.name = name;
this.age = age;
// 这里返回 6
return 6
}
// 使用 new 操作符创建 Person 的实例
const person1 = new Person('qdxs', 18);
console.log(person1.name); // 输出: qdxs
console.log(person1.age); // 输出: 18
console.log(person1 instanceof Person); // 输出: true
console.log(person1.__proto__ === Person.prototype); // 输出: true
上面三个例子中,构造函数返回一些基本类型,在使用 new
生成的对象都是返回新创建的对象。
构造函数返回非空对象
// 定义一个构造函数
function Person(name, age) {
// this 指向新创建的对象
this.name = name;
this.age = age;
// 这里返回任一个对象
return { name: 'xiaoming', age: 16 }
}
// 使用 new 操作符创建 Person 的实例
const person1 = new Person('dzq', 30);
console.log(person1.name); // 输出: xiaoming
console.log(person1.age); // 输出: 16
console.log(person1 instanceof Person); // 输出: false
console.log(person1.__proto__ === Person.prototype); // 输出: false
上面例子中,构造函数返回一个非空对象:
return { name: 'xiaoming', age: 16 }
结果 new
操作符返回的值就是该非空对象。
手动实现 new 操作符
function myNew(constructor, ...args) {
// 1. 创建一个新的空对象
const instance = {};
// 2. 设置原型链
instance.__proto__ = constructor.prototype;
// 3. 绑定 this,并调用构造函数
const result = constructor.apply(instance, args);
// 4. 处理返回值
if ((typeof result === 'object' && result !== null) || typeof result === 'function') {
// Object、Array、Function
return result;
} else {
return instance;
}
}
很多人在手动实现 new
操作符时,只考虑了对象和数组的返回值,却忽略了 Function
类型也需要特殊处理。让我们看一个例子:
使用原生 new
操作符
// 构造函数返回一个函数
function ConstructorWithFunction() {
this.num = 666;
return function() {
console.log('I am a function!');
};
}
// 使用原生new操作符
const obj1 = new ConstructorWithFunction();
console.log(typeof obj1); // 输出: 'function'
console.log(obj1.num); // 输出: undefined,因为返回的是函数而不是对象
使用忽略了 Function
类型的wrongMyNew
function wrongMyNew(constructor, ...args) {
const instance = {};
instance.__proto__ = constructor.prototype;
const result = constructor.apply(instance, args);
// 错误:只检查对象类型,忽略了函数
if (typeof result === 'object' && result !== null) {
return result;
} else {
return instance;
}
}
const obj2 = wrongMyNew(ConstructorWithFunction);
console.log(typeof obj2); // 输出: 'object',这是错误的!
console.log(obj2.num); // 输出: 666,但这不是我们期望的结果
使用考虑 Function
类型的myNew
const obj3 = myNew(ConstructorWithFunction);
console.log(typeof obj3); // 输出: 'function',这才是正确的!
调用 myNew 模拟 new 生成对象
// 定义一个构造函数
function Person(name, age) {
// this 指向新创建的对象
this.name = name;
this.age = age;
}
// 使用自定义的 myNew 函数来创建 Person 的实例
const person3 = myNew(Person, 'xiaoliu', 28);
console.log(person3.name); // 输出: xiaoliu
console.log(person3.age); // 输出: 28
console.log(person3 instanceof Person); // 输出: true
console.log(person3.__proto__ === Person.prototype); // 输出: true
总结
new
操作符的核心作用是将一个普通的函数调用转换为构造函数调用,通过以上五个步骤创建并返回一个新的对象实例。理解这个过程对于深入理解 JavaScript 的面向对象编程非常重要。
关键点: 在手动实现 new
操作符时,一定要记住 Function
类型也是需要特殊处理的返回值类型,这是很多开发者容易忽略的细节!

优网科技秉承"专业团队、品质服务" 的经营理念,诚信务实的服务了近万家客户,成为众多世界500强、集团和上市公司的长期合作伙伴!
优网科技成立于2001年,擅长网站建设、网站与各类业务系统深度整合,致力于提供完善的企业互联网解决方案。优网科技提供PC端网站建设(品牌展示型、官方门户型、营销商务型、电子商务型、信息门户型、微信小程序定制开发、移动端应用(手机站、APP开发)、微信定制开发(微信官网、微信商城、企业微信)等一系列互联网应用服务。