首先需要知道js在new的过程中做了什么:
new 一个构造函数的时候 会生成一个新的执行上下文 指向这个返回的实例,而且还会基于实例的隐士原型指向构造函数的显示原型的原则,把这个返回的实例的__proto__ 指向构造函数的prototype 下边来代码说明一下:
1:首先实现一个最老生常谈的 原生 new方法
function Person() {
this.name = 'person'
console.log(arguments)
}
Person.prototype.say= function () {
console.log("say hi")
}
var p = new Person(1,2,3);
console.log(p.name)
p.say();
打印:
[Arguments] { ‘0’: 1, ‘1’: 2, ‘2’: 3 }
person
say hi
2:现在的需求是自己实现一个Mynew的方法 能够实现上方new的所有功能(之前被阿里面试官面试的时候问到过这个问题,不保证你以后面试不会遇上这个问题喔……)
我们来手动实现一下吧 其实知晓了原理 实现起来还是挺简单的:
function Mynew(){
var obj = {}
Person.apply(obj,arguments)
Object.setPrototypeOf(obj, Person.prototype) // 实际就是 obj.__proto__ = Person.prototype; ES6的写法
return obj;
}
let myP = Mynew(1,2,3);
console.log(myP.name)
myP.say();
同样打印;
打印:
[Arguments] { ‘0’: 1, ‘1’: 2, ‘2’: 3 }
person
say hi
至此自己手写JS new的方法就已经实现了 然后这里指定了Person为构造函数为固定值,为了富有扩展性,我们稍加改动即可, 进阶版代码为:
function Mynew(){
var obj = {}
let constructor = [].shift.call(arguments);
let args = [].slice.call(arguments);
constructor.apply(obj,args)
Object.setPrototypeOf(obj, constructor.prototype) // 实际就是 obj.__proto__ = Person.prototype; ES6的写法
return obj;
}
let myP = Mynew(Person,1,2,3);
console.log(myP.name)
myP.say();