在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前言当你 new 一个构造函数时发生了什么? “众所周知”的三步: 创建一个空对象,将它的引用赋给 this,继承函数的原型;通过 this 将属性和方法添加至这个对象;最后返回 this 指向的新对象,也就是实例。 一般来说在js中大概是这样的: function Mynew(parent,...rest){ let obj={}; obj.__proto__=parent.prototype; let res=parent.apply(obj,rest); return typeof res=="object"?res:obj; }
但通常我们还能见到另一种写法: function Mynew_2(parent,...rest){ let child=Object.create(parent.prototype); let result=parent.apply(child,rest); return typeof result=="object"?result:child; } 这两种实现的不同无疑引起了我的兴趣! Object.create()是怎么实现的?我们来看一段代码: var Best1=function(){ this.a=2; } var o1=Object.create(Best1); var o2=Object.create(Best1.prototype); console.log(o1.a); // undefined console.log(o2.a); // undefined 可以看到,以 o1 为例, 再来看另一段代码: var Best=function(){ this.a=2; } Best.prototype.a=3; var o1=Object.create(Best); var o2=Object.create(Best.prototype); console.log(o1.a); // undefined console.log(o2.a); // 3 到这里,我似乎明白了什么,又似乎没明白… 我决定这么做: let b=new Best(); console.log(b); console.log(Best.prototype); 恍然大悟! 原来我们平时说的 “当读取实例属性时,如果找不到,就会查找与对象关联的原型中的属性;如果还找不到,就去找原型的原型,直到最顶层( ! 那 console.log(b.__proto__); console.log(Best.prototype); 哦!这就是我们常听到的“实例的 那现在回过头来,打印一下 o2 这个对象: console.log(o2); 你有没有想到什么? 根据上面所描述的那样,o2 就是 Best 的实例啊! 所以说, 但 o1 仍然“不为所动”! 所以我们能否猜测:在 Object.create=function(o){ let F=function(){}; F.prototype=o; return new F(); } 为什么这里要用函数再 new 的方式?而不是直接用对象去接收? 这和“为什么vue中data是一个函数而不是直接的对象”其实是一个问题:JavaScript中的对象是引用类型,在一个实例中改变某一个元素的值其余实例的值都会发生改变! 而通过create函数则不会: 总结到此这篇关于JavaScript中实现new的两种方式的文章就介绍到这了,更多相关JS实现new的方式内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论