论坛首页 Web前端技术论坛

javascript prototype 值引用分析

浏览 2611 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-02-08   最后修改:2012-02-08

关于javascript 中prototype的值被实例对象继承的方式的讲解已经有很多了。今天开发operamasks-ui的时候遇到了一个问题,还是觉得值得拿出来讲讲。

首先有一个对象:

 

function a(){}; 
a.prototype.xx=['a','b','c'];
 

 然后新建3个示例:

 

var a1 = new a(); 
var a2 = new a(); 
var a3 = new a();
 

 然后对示例a1和a3的xx属性进行修改:

 

a1.xx = ['a'];
a3.xx.push(12);
 

 最后请问a1.xx,a2.xx和a3.xx分别是多少。由于我以前的不理解,一直以为这三个值都是一样的。结果却是:

a1.xx = ['a'],a2.xx = ['a','b','c',12],a3.xx = ['a','b','c',12]


由于数组是高级javascript对象,因此func a()的实例对象中的xx属性值都是引用到同一个地方的。当a1.xx = ['a']时实际上是新建了一个数组然后把引用给了a1.xx属性。

对于a.prototype.xx 是没有影响的。而a3.xx.push(12)才会真正操作了a的prototype上面的xx,因此a2.xx也跟着改变了。


总结一句,不想被实例对象共享的属性还是不要放到prototype中好。

 

   发表时间:2012-02-09  
恩,学习了,数组是对象。。。
0 请登录后投票
   发表时间:2012-02-09  
应该是,非原始(primitive)类型的默认值不要放在原型中
0 请登录后投票
   发表时间:2012-02-09  
JS的这一套奇淫技巧  有时候真崩溃
0 请登录后投票
   发表时间:2012-02-14  
passionke 写道
JS的这一套奇淫技巧  有时候真崩溃

个人感觉当熟悉这些“奇淫技巧”后对于开发还是利大于弊的
0 请登录后投票
   发表时间:2012-03-15  
a3.xx.push(12);  这就是在xx上执行push方法,前提是a3.xx存在,因此查找原型这个xx变量,在原型链上找到了xx,也就是a.prototype.xx,所以执行的push操作是往原型的xx上push。而a1.xx = ['a']就是普通的变量定义,a1自己拥有了xx这个变量,如果执行a1.xx.push(12),那么a1.xx就是['a',12]了
0 请登录后投票
   发表时间:2012-03-19  
weakfi 写道

关于javascript 中prototype的值被实例对象继承的方式的讲解已经有很多了。今天开发operamasks-ui的时候遇到了一个问题,还是觉得值得拿出来讲讲。

首先有一个对象:

 

function a(){}; 
a.prototype.xx=['a','b','c'];
 

 然后新建3个示例:

 

var a1 = new a(); 
var a2 = new a(); 
var a3 = new a();
 

 然后对示例a1和a3的xx属性进行修改:

 

a1.xx = ['a'];
a3.xx.push(12);
 

 最后请问a1.xx,a2.xx和a3.xx分别是多少。由于我以前的不理解,一直以为这三个值都是一样的。结果却是:

a1.xx = ['a'],a2.xx = ['a','b','c',12],a3.xx = ['a','b','c',12]


由于数组是高级javascript对象,因此func a()的实例对象中的xx属性值都是引用到同一个地方的。当a1.xx = ['a']时实际上是新建了一个数组然后把引用给了a1.xx属性。

对于a.prototype.xx 是没有影响的。而a3.xx.push(12)才会真正操作了a的prototype上面的xx,因此a2.xx也跟着改变了。


总结一句,不想被实例对象共享的属性还是不要放到prototype中好。

 

一个是你给实例变量的一个成员赋值。一个是直接对对象原型的成员操作,而该属性所有实例共享。你执行一下delete a1.xx。再去打a1.xx,全都一样。

 

0 请登录后投票
   发表时间:2012-03-19  
这个是值类型跟引用类型的区别而已。原型会共享。
修改原型的引用,当然会导致其他引用此原型的实例变化。
a1是切断了引用,所以不会变化。
楼主要把问题搞明白,说清楚。不要说不要这样,就完了。
0 请登录后投票
   发表时间:2012-03-19  
因为prototype的属性是读操作, 如果是写操作,将会直接在对象上产生,而读取对象属性的时候,对象的的属性是高于原型属性的,所以会产生覆盖的效果
0 请登录后投票
   发表时间:2012-03-19  
wjyuian 写道
a3.xx.push(12);  这就是在xx上执行push方法,前提是a3.xx存在,因此查找原型这个xx变量,在原型链上找到了xx,也就是a.prototype.xx,所以执行的push操作是往原型的xx上push。而a1.xx = ['a']就是普通的变量定义,a1自己拥有了xx这个变量,如果执行a1.xx.push(12),那么a1.xx就是['a',12]了


支持
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics