解读js中的proto

js中有两个隐含的属性prototype、__proto__。(prototype通过创建的function来访问,__proto__是任何对象都可以访问的属性)

通过下面几个例子来详细分析一下这两个属性的区别:

 

例子1:

能看出来只有原型,即构建function的变量a1才有prototype属性,而new出来的对象不存在prototype属性,

但__proto__属性都存在,那是因为__proto__属性是对象的隐含属性,只要对象被创建出来就会附带这个属性。

 

例子2:

由于例1中,a1.prototype和a2.__proto__返回的都是object,而这个例子a1.prototype和a2.__proto__完全相等,由此可知他们俩指向的是同一个对象。

 

例子3:


首先,通过a1.prototype方式,给a1添加了一个内部属性a1_1,再此通过a2.a1_1()和a2.__proto__.a1_1()都能获取到。

因为a2对象是在a1_1之前创建的,所以a2.__proto__仅仅是一个指针,指向a1.prototype。

(在上图a2最后的展开图中也能看的出来,a2中保存的是a1的地址,而a2.a1_1之所以能直接引用是因为,new出来的对象首先先从自身寻找,如果寻找不到再从__proto__中找)

 

原型链(prototype):是对原型的链接,原型就是创建function的变量,所以任何new出来的对象都是对原型的链接。

 

例子4:

通过Object.create来创建原型链的对象等同于new(因为语法就是Object.create(proto, [ propertiesObject ]),第一个参数固定就是原型)

 

例子5:

在例子3中,通过a1.prototype.a1_1来进行赋值,后面的对象都可以访问到。

但是通过a1.prototype = {}的方式来构造方法,会把a1的原型链接到新的区域,而a2和a3还是指向原来的区域。

看来a1.prototype = {}的方式构造原型,只能在new之前。

 

接下来再看看如何方便的使用proto

例子6:

这是通过prototype来构造内部的属性和函数通过外部来访问

 

例子7:克隆

通过 a5.prototype = new a1() 来把a1的原型赋给a5,所以a5就变成了与a1相同构造的另一个function了,此时再修改a5的原型也不会影响到a1,这就是克隆的原理。

注明:克隆只是克隆原型(即function构建的变量),如果new出来的对象就不需要克隆了,多new几个对象就像相当于克隆对象了。

 

 

补充说明:原型的设计模式只针对于function构建出来的,因为只有function构建出来的才有prototype属性。

 

下面再来看看原型链的好处:

例子7:

a7是正常模式构造的原型,a1是通过原型链构造的原型,能看出来正常模式构建的原型是块区域存储的,而原型链构建的原型是以地址形式存储的

好处1:原型链更省资源

通过new一个新对象来比较,正常构建的a8的内部函数都存在于本身,构建完无法再修改内部函数和属性;

而原型链构建的a9的内部函数存在于原型链中,可以通过原型链再次修改。

好处2:方便修改原型,而在上面例子3中也能看出来修改后的内部函数和属性应用于所有通过该原型new出来的对象。

 

 

再多说一嘴,我查了一下dojo内部的函数,发现declare函数就是通过原型链实现的(包括继承也是),否则像咱们那么臃肿的代码那么点的硬件资源根本吃不消O(∩_∩)O

js中有两个隐含的属性prototype、__proto__。(prototype通过创建的function来访问,__proto__是任何对象都可以访问的属性)通过下面几个例子来详细分析一下这两个属性的区别:例子1:能看出来只有原型,即构建function的变量a1才有prototype属性,而new出来的对象不存在prototype属性,但__proto__属性都存在,那是因为__proto__属性是对象的隐含属性,只要对象被创建出来就会附带这个属性。例子2:由于例1中,a1.prototype和a2.__proto__返回的都是object,而这个例子a1.prototype和a2.__proto__完全相等,由此可知他们俩指向的是同一个对象。例子3:

posted @ 2017-05-10 14:38  冉夜  阅读(1168)  评论(0编辑  收藏  举报