手动实现一个 new 操作符理解
网上看了一些手动实现 new 操作符的方法和效果,现在来总结下
第一种方法
function new1(func) {
var newObj = Object.create(func.prototype); // 创建一个继承自 func.prototype 的新对象
var returnObj = func.apply(newObj, Array.prototype.slice.call(arguments, 1)); // 截取 new1 函数第二个以及第二个之后的参数, 在 newObj 作用域内执行改造函数 func
if ((typeof returnObj === “object” || typeof returnObj === “function”) && ret !== null) {
return returnObj;
} // 如果传入参数中的构造函数执行后的 returnObj 是“对象”类型 (比如 new1(Object)), 那么这个对象会取代 newObj 作为返回的对象
return newObj;
}
第二种方法
function new2(func) {
return function() {
let newObj = {
__proto__: func.prototype // 新生成一个对象, 且新对象的原型对象继承自构造对象的原型对象
}
var returnObj =func.apply(obj, arguments) // 以第二次执行函数的参数, 在 obj 作用域中执行 func
if ((typeof returnObj === “object” || typeof returnObj === “function”) && returnObj !== null) {
return returnObj;
} // 同理,returnObj 是“对象”类型 (比如 new1(Object)), 那么这个对象会取代 newObj 作为返回的对象
return newObj
}
}
和原生对象构造方式对比
var object1 = new1(Object);
var object2 = new2(Object)();
var object3 = new Object();
console.dir(object1)
console.dir(object2)
console.dir(object3)
在控制台中查看结果
没有区别。再假定一个自定义的构造函数进行对比
function person(name, age) {
this.name = name
this.age = age
}
var obj1 = new1(person,’zhus’,25);
var obj2 = new2(person)(‘zhus’,25);
var obj3 = new person(‘zhus’,25);
console.dir(obj1)
console.dir(obj2)
console.dir(obj3)
对比结果
也没有区别。