new的原理
现在要创建一个新的对象,比如这个对象是一个人(Person),代码如下:
javascript
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
console.log(this.name);
};
}
let person1 = new Person("Walter White", 50, "Chemist");
当使用new操作符的时候,进行以下操作:
- 在内存中创建一个新的对象
- 将这个对象的
__proto__
指向构造函数的prototype
(原型对象) - 让
this
指向这个新的对象 - 执行构造函数内部的代码,给这个对象添加属性与方法
- 返回这个新的对象(所以构造函数里面不需要写
reutrn
)

下面来看下代码上的实现:
javascript
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
console.log(this.name);
};
}
function myNew(Class, ...args) {
// 1. 在内存中创建一个新的对象
const o = new Object();
// 2. 将这个对象的__proto__指向构造函数的prototype(原型对象)
o.__proto__ = Class.prototype;
// 3.让this指向这个对象
// 4.指向构造函数的代码,给这个对象添加属性与方法
const result = Class.call(o, ...args);
// 5.返回这个新对象
return typeof result === "object" ? result : o;
}
// 使用new创建
let person1 = new Person("Walter White", 50, "Chemist");
// 使用手写函数创建
let person2 = myNew(Person, "Walter White", 50, "Chemist");
console.log(person1); // Person {name: 'Walter White', age: 50, job: 'Chemist', sayName: ƒ}
console.log(person2); // Person {name: 'Walter White', age: 50, job: 'Chemist', sayName: ƒ}
补充
myNew
函数优化写法:
javascript
function myNew(Class, ...args) {
// 1. 在内存中创建一个新的对象
// 2. 将这个对象的__proto__指向构造函数的prototype(原型对象)
const obj = Object.create(Class.prototype);
// 3.让this指向这个对象
// 4.指向构造函数的代码,给这个对象添加属性与方法
let result = Class.apply(obj, [...args]);
// 5.返回这个新对象
return typeof result === "object" ? result : obj;
}
const obj = Object.create(Class.prototype);
等价于
javascript
// 1. 在内存中创建一个新的对象
const o = new Object();
// 2. 将这个对象的__proto__指向构造函数的prototype(原型对象)
o.__proto__ = Class.prototype;