我们可能平时都接触到new方法,通过new关键字创建了一个实例。比如new Vue();那么当我们new的时候究竟做了什么?今天看了篇分享,自己实践了下个,感觉有必要和大家一起分项一下啊。
众所众知当我们用new构造一个实例的时候,我们构造出来的实例会有两个属性,__proto__指向构造函数的原型,constructor:指向构造函数,同时构造函数也有一个prototype属性指向原型。
我们来举个例子,function animal(name){this.name = name}--构造函数; animal.prototype.sayName=function(){console.log(this.name)};--构造函数的原型,
var dog = new animal(‘dog’);--构造函数的实例
好了,接下来我们开始讲new,new是一个关键字当我们new 一个构造函数的时候做了哪些事呐,一,创建了一个实例对象,并且实现了上边的一些关联。那么new是如何实现的呐?我们来试着写一个我们自己的new方法
function selfNew(){
var obj = new Object();
var con = [].shift.call(arguments);
console.log(con);
debugger;
obj.__proto__ = con.prototype;
con.apply(obj,arguments);
return obj;
}
里边已经有了断点,大家可以调试下。可能大家会疑惑这条语句[].shift.call(arguments);我也小小的迷惑了下,查了下mdn的shift方法,发现原来shifit是有返回值的。一直以为shift只是删除了元素。可能大家会有疑惑,我来说一下。我们调用数组的shift方法删除arguments的第一个元素并返回第一个元素,arguments是什么呐?回想一下我们怎么new的,new person('a',1);selfNew(animal,'dog',12);当我们调用selfNew时,arguments的值为[animal,'dog',12]这是个类数组。然后我们用shift删除了animal并且返回给con接收,这个时候con就是我们的构造函数了。
接下来obj是一个new的对象,也是用来代替我们构造函数的实例的。我们首先让obj.__proto__指向了构造函数con的原型,然后我们需要给构造函数的传递的参数进行处理了。上边我们把arguments的第一个函数删除了,那么这时候arguments中的值就是['dog',12];现在要做的就是把这个两个参数传递给我们的构造函数con,因此我们利用apply方法,con.apply(obj,argumetns);这个时候con里边的this就是obj也就是我么返回的实例对象了。最后我们把obj返回去。好了,万事大吉!当然还有些特殊的情况需要处理,下一篇再说吧。