JavaScript-关于javascript中原值被覆盖的疑惑?

JavaScript-关于javascript中原值被覆盖的疑惑?

虐人心 发布于 2017-10-17 字数 249 浏览 1089 回复 1

有一下五行代码:

<script type="text/javascript">
1) var obj = obj1 = {};
2) obj1['y'] = 3;
3) obj['x'] = obj1;
4) obj1['y'] = 4;
5) alert(obj['x']['y']);
</script>

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

虐人心 2017-11-05 1 楼

这个不难理解,JavaScript对变量赋值是采用复制还是引用是这样定义的:“如果赋值的是基本类型则是复制,其它的都是引用”。看到这相信你就已经明白了。
引用:对象、数组、函数
复制:数字、布尔

这里字符串类型则比较特殊,因为要根据程序的上下文环境来判断到底是传值还是传引用。所以就不解释了。

针对你的问题,由以上可以看出,var obj = obj1 = {}; 是一个对象,无论你是单独声明还是分开声明,都是一样的,它是采用引用赋值,所以最后alert(obj['x']['y'])的结果则肯定是4。搞定!

对于你的疑问我再说明一下:
var obj = obj1 = {};//此时变量obj和obj1指定同一个内存地址假设为:M(M的内存为哈稀表),值为空
obj1['y'] = 3; //为obj1的对象属性y赋值为3,即在内存为obj1['y']分配一块内存假设内存地址为:O,并把M中的M(y)指向内存地址O
obj['x'] = obj1; //为obj的对象属性x赋值为obj1,此时基于对象是基于引用赋值,所以并不为obj['x']分配内存,而是把M中的M(x)指向内存地址M
var t = obj['y']; //为t变量赋值,此时把t指向内存地址M(y),即O:M(y)->O
obj1['y'] = 4; //此时为内存地址为M(y)所指向的内存地址为O的重新赋值为4,赋值前发现不止一个变量指向该地址,t也指向了该地址,基于Coyp On Write原则,必须为t重新分配一块存,并把内存地址O的内存复制一份t变量的内存,然后才为obj['y']所指向的内存O赋值为4
alert(obj['x']['y']); //由于obj['x']的内存M(x)指向的是M,而obj['x']['y']即M(y)指向的是O,它的值为4,所以这个为4
alert(t); //由于变量t已经为新分配的内存地址,所以它的值还是3

//以下是对你评论的疑问加以说明
var obj = new String('abc'); //此时为变量obj分配内存的地址假设为:M,并赋值为:"abc"
str = obj; //此时为引用赋值 ,变量str也指向内存地址为:M
obj = 'def'; //基于Copy On Write的原则,由于对变量obj重新赋值,发现obj所指向的内存地址M还有另外的变量str指向它,那么必须为str重新分配一块内存为N,并把当前内存地址M中的值即"abc"复制到新分配的内存N中,再把obj所指向的内存地址M赋值为:"def"
alert(str); //变量str指向的内存地址为N所存的值是"abc"
alert(obj); //变量obj指向的内存地址为M所存的值是"d