首先我们来回顾一下 new 操作符的作用。new 操作符用来调用构造函数,并返回一个对象,该对象可以访问构造函数内部的属性和方法,也可以访问构造函数的原型对象的属性和方法。 那么,调用 new Foo() 的时候,new 到底做了什么呢?
- 在内存中创建一个新的对象;
- 构造函数内部的 this 被赋值为这个新对象(继承实例属性);
- 将新对象的 proto 指针指向 Foo 的原型对象(继承原型属性);
- 执行构造函数内部的代码(给新对象添加属性);
- 如果构造函数返回非空对象,则返回该对象,否则,返回新创建的对象。
let myNew = function () {
// 注意:箭头函数没有自己的 this,arguments,super 和 new.target
// 所以这里不能使用箭头函数
let obj = new Object()
// 获取构造函数
let arg = Array.prototype.shift.call(arguments)
// 将 obj 对象的 __proto__ 指针指向构造函数的原型对象,参考原型继承
obj.__proto__ = arg.prototype
// 改变构造函数的作用域,使其指向新对象
const res = arg.apply(obj, arguments)
// 如果构造函数返回对象,则返回该对象,否则,返回新创建的对象,即obj
return typeof res === 'object' ? res : obj
}
// test
let Animals = function (name, age) {
this.name = name
this.age = age
// return {
// name: 'hhh'
// }
}
const res = myNew(Animals, 'Sugary', 12)
console.log(res.name) // 'Sugary'