本人新手想问一个小白问题,先上一段演示代码:
javascript
var obj1={color:"red"}; var obj2=obj1; obj2.color="green"; alert(obj2.color); //green obj2=null; alert(obj2.color); //报错,undefined alert(obj1.color); //green
有一个地方实在不是很清楚,就是当obj2=null后,为什么obj1任然存在?
按理说js的说法引用类型存放的是数据的地址,当我对obj2进行操作的时候实际是对obj2存放的地址那里的数据进行操作,所以我把obj2的颜色改了,obj1的颜色也一起改了。
可是当我把obj2设置为null后,obj1任然在?难道说=null操作是直接把obj2存的地址给清空了,而其他操作则是“寻址操作”?
这个绝对不是 小白的问题
这涉及到了 ECMAScript = 这个运算符的原理了;
大家都知道赋值有 按值传递、按引用传递这两种类型,其实ECMAScript中还有一种 叫 按共享传递;
即:修改参数的属性将会影响到外部,而重新赋值将不会影响到外部对象。
ECMAScript代码:
即两个标识符(名称绑定)绑定到内存中的同一个对象, 共享这个对象:
而重新赋值分配,绑定是新的对象标识符(新地址),而不影响已经先前绑定的对象 :
即现在foo和 bar,有不同的值和不同的地址:
再强调一下,这里所说对象的值是地址(address),而不是对象结构本身,将变量赋值给另外一个变量——是赋值值的引用。因此两个变量引用的是同一个内存地址。下一个赋值却是新地址,是解析与旧对象的地址绑定,然后绑定到新对象的地址上,这就是和按引用传递的最重要区别。
此外,如果只考虑ECMA-262标准所提供的抽象层次,我们在算法里看到的只有“值”这个概念,实现传递的“值”(可以是原始值,也可以是对象),但是按照我们上面的定义,也可以完全称之为“按值传递”,因为引用地址也是值。
然而,为了避免误解(为什么外部对象的属性可以在函数内部改变),这里依然需要考虑实现层面的细节——我们看到的按共享传递,或者换句话讲——按安全指针传递,而安全指针不可能去解除引用和改变对象的,但可以去修改该对象的属性值。
参考阅读: 深入理解JavaScript系列(19):求值策略(Evaluation strategy)