javascript 中 new 操作符的原理
我们知道采用 new 操作符会创建一个对象实例,例如:let p = new Person();
;而具体是怎样创建的呢?
实际上会执行下面的三个步骤:
- 创建一个空对象
- 这个空对象指向该对象的原型对象
- 更改该对象的this指向这个空对象(修改 作用域 )
用代码解释
// 1. 创建一个空对象
let p = {};
// 2. 这个空对象指向该对象的原型对象
p.__proto__ = Person.prototype;
// 3. 更改该对象的this指向这个空对象(修改 作用域 )
Person.apply(p);
根据原理我们可以自己创建一个实现 new 操作符的函数
function Person(name = '晨米酱', age = 20) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
return '大家好,我是' + this.name;
}
function New() {
let Constructor = Array.prototype.shift.call(arguments)
// 使用Object.create使得新创建的对象和原有对象解耦
let obj = Object.create(Constructor.prototype)
let res = Constructor.apply(obj,arguments)
// new一个实例的时候,如果没有return,会根据构造函数内部this绑定的值生成对象,如果有返回值,就会根据返回值生成对象,为了模拟这一效果,就需要判断apply后是否有返回值
return typeof res === 'object' ? res : obj
}
// console.log(new Person()); //Person { name: 'chenmijiang', age: 20 }
let p1 = New(Person);
console.log(p1, p1.sayHi()); //Person { name: '晨米酱', age: 20 } 大家好,我是晨米酱
let p2 = New(Person,'张三', 19);
console.log(p2, p2.sayHi()); //Person { name: '张三', age: 19 } 大家好,我是张三