javascript——赋值

js赋值

=相对大家来说这个符号应该是很熟悉的了,但是在我们的JavaScript中,它是怎么做到对不同数据类型实现赋值操作的呢,不知道同学们有没有仔细研究过…

案例

var a = {n:1};
var b = a;
a.x = a = {n:2};
alert(a.x);
alert(b.x);

这是一个比较常见也经典的js面试题,这个除了对=操作的考察外,更重要的是一个连等操作的考察,以及js如何存贮不同数据类型,但是赋值操作的理解才是根本

解析

  1. 首先对于基础数据类型的赋值操作,就是简单的栈内存分配一个地址储存变量

  2. 但是对于引用类型的赋值操作,实际是在栈内存创建一个所谓的指针,是在就是地址变量,让后这个地址指向的实际是堆内存的某个存储了引用类型数据的内存地址

上面这个问题,我们需要知道几个基础点:
1.变量赋值是从右到左的操作;
2.连等操作a=b=c,可以看成b=ca=b,注意只是可以看做,实际a=b=c是不可以拆分的
3..运算符的优先级是高于=

重点
js在实现赋值操作时,对于左侧变量会有个优先操作,就是先确定它所在的栈地址,如果没有就给他创建一个值为null(是不是null,我不确定)的栈地址。

所以针对a.x = a = {n:2};
step1. 对于a={n:2},先在堆内存中存储{n:2},然后找到a所在的栈内存地址,并修改这个地址中存储的指向原本指向{n:1}的变量指针,修改后的指针指向{n:2}所在的堆内存
step2.对于a.x=a,此时右边的a已经是栈内存中修改过后指向{n:2}的指针了,然后此时我们需要确定左边的a.x是否在栈内存中有值,前面提过这是个优先操作,所以此时的a还是原本指向{n:1}的栈内存的指针,然后执行.操作符,发现{n:1}对象没有x字段所以会创建一个栈内存指针,然后执行赋值操作,这个新创建指针就指向修改后的a的栈内存指针

所以最后结果

alert(a.x); // undefined
alert(b.x); // {n:2}

分享个网站可以看每一步的实现指向
http://pythontutor.com/visualize.html#mode=display

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注