现在遇到一个引用传递的问题,用代码说明吧
var Lan = function(){};
var Attr1 = function(){
this.name = 'attr1';
}
var Attr2 = function(){
this.name = 'attr2';
}
Lan.prototype.attr = new Attr1();
var lan = new Lan();
var obj = lan.attr;//这一步不应该是传递的Lan原型链上的引用吗
console.log(obj1);//输出Attr1 {name: "attr1"}
Lan.prototype.attr = new Attr2();//Lan原型链的属性改变,指向Attr2的对象,那obj不也应该指向Attr2的对象?
console.log(obj);//输出Attr1 {name: "attr1"},但结果却不是这样
[1]obj 和 Lan.prototype.attr 同时指向 new Attr1() 创建的对象
[2]Lan.prototype.attr重指向 new Attr2()创建的对象,而obj 指向的对象没有变(new Attr1() 创建的对象没有消失,内存中依旧存在)
[3]obj 指向的对象指向的还是原来的对象
简化下,大概是这样吧
你下面打印错了,你改变原型之后,打印的还是之前new的那个lan,所以当然还是一样的结果,上代码,我手机端,无法编辑代码格式,你凑合看,主要我下面new了一个新的lan1,然后打印lan1,也就是更改之后的,
var Lan = function(){};
var Attr1 = function(){
this.name = 'attr1';
}
var Attr2 = function(){
this.name = 'attr2';
}
Lan.prototype.attr = new Attr1();
var lan = new Lan();
var obj = lan.attr;
console.log(obj.name)
Lan.prototype.attr = new
Attr2();
var lan1=new Lan;
var obj1=lan.attr;
console.log(obj1.name);//输出Attr2
我们可以分解下看看:
最后, 如果console.log(lan.attr), 应该得到[Object] {name: 'attr2'}
最后如果你
console.log(lan.attr)
,那结果就是Attr2 {name: "attr2"}
,因为你obj
还是指的那个对象。相当于
b = 1;a = b;b = 2
;这时,a的value为1
,而不是2
。一、obj 和 lan 原型对象 attr 属性同时指向 object { name: 'attr1' }
二、obj 依旧指向 object { name: 'attr1' }; lan 原型上的 attr 指向 object { name: 'attr2' }
Javascript中的赋值策略 不仅仅是 按值传递、按引用传递 这么简单;
看一个在 stackoverflow 上的回答:Javascript by reference vs. by value:
再来看段代码:
以上为Javascript中赋值会遇到的一些情况,有点偏题了;
这些都只是表现,具体的原理可以看下这篇文章:深入理解JavaScript系列(19):求值策略(Evaluation strategy);
回头来看你遇到的问题:
你遇到的问题 关键在
var obj = lan.attr;
这个赋值引起的;可以这么理解 obj 在赋值的时候 获得了 lan.attr 的内存地址 0xFE;
后面再修改 Lan.prototype.attr的内存地址为 0xFF,并不会影响到 obj;
所以
console.log(obj);
和console.log(lan.attr);
的结果并不一样;