javascript 连等赋值问题(这是从SegmentFault转过来的一个问题)

var a = {n:1};
var b = a; // 持有a,以回查
a.x = a = {n:2};
alert(a.x);// --> undefined
alert(b.x);// --> {n:2}

对于这段代码,大部分人的理解是这样的:========错误的理解=======

对于 a.x = a = {n:2},大部分人的思路应该是:

  1. 先把 {n:2} 赋值给 a
  2. 然后再创建 a.x,将 {n:2} 再赋值给 a.x

这样似乎确实说不通 a.x 的值是 undefined,因为 a.x 确实是被赋值了的啊。
可是事实上,a.x 的值却是 undefined。

再来看一下这个: a = a.x = {n:2}的话,按原先的思路应该是:

  1. 先把 {n:2} 赋值给 a.x,那么也就相当于 b.x = {n:2} 啦
  2. 再把 a 重新指向 {n:2}。那么这是后 a.x 的值确实是 undefined,a 对象 {n:2} 中就没有 x 属性嘛。

按这个思路,上述两种方式的结果应该是不同的。但事实却是a = a.x = {n:2}a.x = a = {n:2}的结果是一致的。所以很明显这个思路不对。

===========================正确的理解是这样的===================

解析器在接受到 a = a.x = {n:2} 这样的语句后,会这样做:

  1. 找到 a 和 a.x 的指针。如果已有指针,那么不改变它。如果没有指针,即那个变量还没被申明,那么就创建它,指向 null。
    a 是有指针的,指向 {n:1};a.x 是没有指针的,所以创建它,指向 null。
  2. 然后把上面找到的指针,都指向最右侧赋的那个值,即 {n:2}

所以执行以后,就有了如下的变量关系图。大家可以慢慢体会下,想通了就很简单的。

如果大家觉得这种理解比较难,可以先按下面一种方式理解,等理解了再过来看看上面的解释

赋值是从右到左的,但不要被绕晕了, 其实很简单,从运算符优先级来考虑

a.x = a = {n:2};

.运算优先于=赋值运算,因此此处赋值可理解为

  1. 声明a对象中的x属性,用于赋值,此时b指向a,同时拥有未赋值的x属性
  2. 对a对象赋值,此时变量名a改变指向到对象{n:2}
  3. 对步骤1中x属性,也即a原指向对象的x属性,也即b指向对象的x属性赋值

赋值结果:

a => {n: 2}
b => {n: 1, x: {n: 2 } }    
时间: 2024-08-04 18:33:23

javascript 连等赋值问题(这是从SegmentFault转过来的一个问题)的相关文章

JavaScript 将多个引用(样式或者脚本)放入一个文件进行引用

1.将样式放入一个文件进行引用 @import url("../media/css/bootstrap.min.css"); @import url("../media/css/bootstrap-responsive.min.css"); @import url("../media/css/font-awesome.min.css"); @import url("../media/css/style-metro.css");

[Html / Javascript / CSS] 当鼠标移至img时,img右上角出现一个叉叉超链接

因为工作上客户需要制作类似FB的图片删除方式 备份一下在论坛上的发问:http://social.msdn.microsoft.com/Forums/zh-TW/0abb451a-e8ac-4f28-ab91-fc028ee14ec9/imgimg?forum=236 以下代码改用jQuery实现 @{ ViewBag.Title = "Index"; } .imgDiv{ display : inline-block; position : relative; } .imgDiv .

JavaScript连等赋值

最近探究js原理的过程中遇到了这个挺有趣的问题. 先贴代码: var a = {n:1} a.x = a = {n:2} alert(a.x) //undefined 在弄懂这个之前,我们先普及一个知识点,就是在javascript运算符中,属性运算符的优先级高于赋值运算符的优先级. 因此,a.x是先于赋值之前就进行的. 就是说,a.x刚开始是undefined的,这是没错的. 接下来我们探究一下连等赋值的赋值顺序: 1.从左往右 a.x赋值为{n:2};然后a赋值为{n:2};a的重新指向重写

javascript给输入框赋值的一个误区

一. 错误的示范 如下代码所示,如果需要用javascript获取id为username1, password1的输入框的值,将其写入id为username2, password2的输入框,那么红线区域的代码是不可取的 这样看到的结果是,alert依次弹出username1, password1的输入框的值,事实上并没有成功的赋值 这是为什么?因为var username2 = document.getElementById("username2").value; 这行代码中usern

JavaScript对象属性赋值操作的逻辑

对象进行属性赋值操作时,其执行逻辑如下所示: 1. 当前对象中是否有该属性?有,进行赋值操作:没有,进行下一步判断. 2. 对象的原型链中是否有该属性?没有,在当前对象上创建该属性,并赋值:有,进行下一步判断. 3. 原型链中该属性是否允许操作?是,在当前对象上创建同名属性,并赋值:否,属性赋值失败. 无论是属性赋值还是新建属性,都是在当前对象上进行的,不会修改原型链!第三种情况下,新建的属性将会覆盖对象从原型链继承来的同名属性.

javascript引用和赋值

1 var arr1=[1,2,3,4];//数组1被创建 指向物理内存的一个地址 2 var arr2=arr1;//数组arr2 被赋值为arr1(引用了arr1); 3 //alert(arr1);//1,2,3,4 4 //alert(arr2);//1,2,3,4 5 /* 6 arr2.push(5) arr2变为1,2,3,4,5 7 由于arr2和arr1 是同一个物理地址的引用,所以 arr1同时被改变 8 */ 9 arr2.push(5); 10 11 //alert(ar

javascript 将函数赋值给变量

midifan.com/moduleuser-index-414525.htmmidifan.com/moduleuser-index-414626.htmmidifan.com/moduleuser-index-414703.htmmidifan.com/moduleuser-index-414725.htmmidifan.com/moduleuser-index-414802.htmmidifan.com/moduleuser-index-414542.htmmidifan.com/modu

字符串的基本操作,初始化和赋值之类的区别,和数据名是一个常量指针不可以改变和赋值(盲点众多)

#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> //一级指针的典型用法 //数组 int a[10] //字符串 //1 C语言的字符串 以零结尾的字符串 //2 在C语言中没有字符串类型 通过字符数组 来模拟字符串 //3 字符串的内存分配 堆上 栈上 全局区 (很重要) //字符数组 初始化 void main51() { //1 指

PHP+JavaScript+HTML变量之间赋值及传递

本文是最近做WAMP网站的学习知识,这做这个网站过程中需要通过新闻通告的超链接显示相应的具体内容,所以就涉及到一些相关变量赋值传递的内容,包括:HTML超链接传递值通过JavaScript显示.JavaScript变量转换成PHP变量.超链接实现传递给PHP连接数据库(重点).PHP输出JavaScript内容. 一. HTML超链接传递值 首先讲述通过HTML超链接<A href=></A>实现跳转,再通过JavaScript实现获取传递的值.代码如下:其中testA.php是超