/**
* 模拟实现new操作符
* @param {Function} ctor [构造函数]
*/
export const newOperator = (ctor) => {
if(typeof ctor !== "function") {
throw new Error("the first params of newOperator must be a func")
}
//ES6 new.target是指向构造函数
newOperator.target = ctor;
//创建一个全新的对象
//并且执行 __proto__ 链接,通过new创建的每个对象将最终被 __proto__ 链接到构造函数的 prototype 对象上
const newObj = Object.create(ctor.prototype);
//除去 ctor 构造函数的其余参数
const argsArr = [].slice.call(arguments, 1);
//生成的新对象会绑定到函数调用的this,也就是this的指向是实例对象
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__ 是浏览器实现的查看原型方案。
// 用ES5 则是:
Object.getPrototypeOf(student1) === Student.prototype; // true
Object.getPrototypeOf(student2) === Student.prototype; // true
网友评论