/**
* 模擬實(shí)現(xiàn)new操作符
* @param {Function} ctor [構(gòu)造函數(shù)]
*/
export const newOperator = (ctor) => {
if(typeof ctor !== "function") {
throw new Error("the first params of newOperator must be a func")
}
//ES6 new.target是指向構(gòu)造函數(shù)
newOperator.target = ctor;
//創(chuàng)建一個全新的對象
//并且執(zhí)行 __proto__ 鏈接,通過new創(chuàng)建的每個對象將最終被 __proto__ 鏈接到構(gòu)造函數(shù)的 prototype 對象上
const newObj = Object.create(ctor.prototype);
//除去 ctor 構(gòu)造函數(shù)的其余參數(shù)
const argsArr = [].slice.call(arguments, 1);
//生成的新對象會綁定到函數(shù)調(diào)用的this,也就是this的指向是實(shí)例對象
const ctorReturnResult = ctor.apply(newObj, argsArr);
const isObject = typeof ctorReturnResult === "object" && ctorReturnResult !== null;
const isFunction = typeof ctorReturnResult === 'function';
if(isObject || isFunction) {
return ctorReturnResult;
}
return newObj;
}
以下例子模擬
function Student(name, age){
this.name = name;
this.age = age;
// this.doSth();
// return Error();
}
Student.prototype.doSth = function() {
console.log(this.name);
};
var student1 = newOperator(Student, '若', 18);
var student2 = newOperator(Student, '川', 18);
// var student1 = new Student('若');
// var student2 = new Student('川');
console.log(student1, student1.doSth()); // {name: '若'} '若'
console.log(student2, student2.doSth()); // {name: '川'} '川'
student1.__proto__ === Student.prototype; // true
student2.__proto__ === Student.prototype; // true
// __proto__ 是瀏覽器實(shí)現(xiàn)的查看原型方案。
// 用ES5 則是:
Object.getPrototypeOf(student1) === Student.prototype; // true
Object.getPrototypeOf(student2) === Student.prototype; // true