javascript:这个代码很是头疼,一直以为js 写的还可以的我,这次又一次认识了自己

foxidea 发布于 2012/02/14 20:01
阅读 1K+
收藏 3
function A(){

}
A.prototype={
	b:{
		c:function(){
			alert('x')
		}
	}
}

var a1 = new A();
var a2 = new A();

a2.b.c();//执行了alert('x')
a1.b.c=2;
alert(a2.b.c)
a2.b.c();// 出错了 为什么?修改了a1.b.c 的值为何影响了 a2.b.c 的???


以下是问题补充:

@foxidea:经过我的反复思考,反复实验,我对这个问题有了新的认识 首先: 当 var a1 = new A(); 的时候,确实是把 原形复制了一份, var a2 = new A(); 也是把原形复制了一份 A.prototyp.b 其实是一个指针, 指向的是 {c:function(){ alert('x')}} 这个对象 所以当 var a1= new A() 的时候,a1.b 也是一个指针而已,执行的和 a2.b 和 A.prototype.b 是一个对象 所以在修改 a1.b.c=2 的时候 , 其实 a1.b === a2.b ===A.prototype.b (2012/11/13 16:34)
加载中
0
mark35
mark35

A你定义是个函数,new A() 的复制结果应该是同一个对象吧?

你 === 比较a1,a2是否相等?

转角遇到鬼
转角遇到鬼
虽然你是对某个实例中的方法进行赋值,但是这2个实例是同一个对象来的,而原型链是针对对象来说的吧,就是说所有的实例实际上都共用同一个原型链上的方法,区别只是那些方法里面的作用域(为各自的实例对象)不同而已,这原理和JAVA中的静态变量一个道理,你虽然new 出2个实例对象来 但是如果通过某一个实例去改变静态变量的值,其他实例在进行访问时静态变量就已经变了。
Andre.Z
Andre.Z
javascript里面,function就是一个类定义了。a1和a2是2个实例对象,必然是不同的,所以===的结果是false。
2
Andre.Z
Andre.Z

A.prototype

用.prototype代表了什么,你弄清楚没?这个是类似java里面的static的,A的所有对象实例都是共用里面的东西,你改了其中的一个,当然会导致其它的也改变。

a1和a2并不是同一个对象,只是属性b是共用的,所以你可以发现alert(a1===a2)是false,alert(a1.b===a2.b)是true。

要实现你说的,试试下面的

function A() {
	this.b={
		c:function() {alert('x');}
	};
}
  
var a1 = new A();
var a2 = new A();

a2.b.c();
a1.b.c=2;
alert(a2.b.c);
a2.b.c();


foxidea
foxidea
嗯,现在总算又认识了一点 prototype,和 this
0
拉登他哥
拉登他哥
瞎扯蛋....
foxidea
foxidea
我也觉得扯淡
0
贰拾壹
贰拾壹

我想这要原因是因为你把b定义成为了一个对象类型,而不是基本类型,A的原型对象的属性如果是基本类型,那么每个 A实例拥有的该属性都是单独的,如果该属性是对象等复合类型的,那么这个属性是所有的A实例 共享的,他们拥有的只是对象的引用。

本人曾经也迷惑,只是理解如果不正确,就算了

0
开源中国首席一失足成千古风流人物以稀为贵
开源中国首席一失足成千古风流人物以稀为贵

javaScript 是解释型的语言,所以他的创建对象方式不同于java等编译型的语言..

java的 new 可以理解为 开辟了一个独立的内存空间.所以 new 几次 就会出现几个内存空间,彼此之间是不影响的..

javascript的 new 只能理解为 "复制"  new 出来的也就自然成了 一个引用.

这样就不难解释你的问题 

当你声明一个A类,  a1修改的A 的结构,a2 自然就变了.

上面为我的理解

具体看看这个

http://blog.csdn.net/spring21st/article/details/6307261

 

 

 

0
bonjour
bonjour
试试:a1.b.c === a2.b.c 就知道了~~
0
antipro
antipro

a1和a2共用同一个protype,所以改了a1.b.c就是改了a2.b.c

0
weilingfeng98
weilingfeng98

var a1 = new A(); //a1.__proto__ == A.prototype

var a2 = new A(); //a2.__proto__ == A.prototype

修改了a1的c方法相当于修改了__proto__也就相当于修改了A的prototype

所以a2会变

0
w
windy.lcx
楼上正解。
0
庸夫俗子
庸夫俗子
本来也觉得自己还行,一看贴子发现,跟楼主差好多。
返回顶部
顶部