在<javascript模式>中,new实现过程描述是下面这样:
1.创建一个空对象,将他的引用指向this,继承构造函数的原型。
2.通过this将属性和方法添加到这个对象
3.最后返回this指向的新对象,也就是实例(如果没有手动返回其他的对象)
大概实现例子如下:
function Person(name,age){ //创建一个空对象,将他的引用指向this,一般是隐式实现 //let this={} //通过this将属性和方法添加到新对象中 this.name=name; this.age=age; //如果没有返回其他对象,则默认返回this指向的这个对象 //return this; }
上面已经很好的解释了new实现过程,不过还是不够完美,没有展示出原型上的属性是怎么继承给实例的。
我在winter大神的重学前端专栏中,看到了比较符合我心意的,同时也是符合原理的描述:
• 以构造器的prototype属性为原型,创建新对象;• 将this(也就是上一句中的新对象)和调用参数传给构造器,执行;• 如果构造器没有手动返回对象,则返回第一步创建的新对象,如果有,则舍弃掉第一步创建的新对象,返回手动return的对象。
我们手动实现一个new,代码如下:
function NewRelize(){ //获取构造器 和 构造器后的参数 (数组的shift方法删除第一项,并且返回被删除的项);删除后arguments就剩下传递的参数了 let Con=Array.prototype.shift.call(arguments); //以构造器的prototype为原型,创建新对象 let newObj=Object.create(Con.prototype); //将新对象和调用参数传给构造器,执行 let result=Con.apply(newObj,arguments); //如果构造器没有手动返回对象,则返回新创建的对象 return typeof result=='object'?result:newObj; }
function Person(name,age){ this.name=name; this.age=age; } let newj=NewRelize(Person,'zhangsan',11); console.log(newj.name); console.log(newj.age);