首页 > 试题广场 >

请问以下JS代码输出的结果是什么? let obj = {

[单选题]
请问以下JS代码输出的结果是什么?
let obj = {
  num1: 117
}
let res = obj;
obj.child = obj = { num2: 935 };
var x = y = res.child.num2;
console.log(obj.child);
console.log(res.num1);
console.log(y);


  • 117、117、undefined
  • 117、117、935
  • undefined、117、935
  • undefined、117、undefined
let obj = { num1: 117 } 
    把obj放在栈里,把 { num1:117} 放在堆里,让obj指向堆里的 { num1:117 }     
    let res = obj;
把res放在栈里,把res也指向堆里的 { num1:117 }     
    
    
    
    
    
    obj.child  =  obj  =  { num2: 935 };
重点:赋值操作先定义变量(从左到右),再进行赋值(从右到左)     

 定义变量    obj.child,给堆里的{ num1:117 }加一个child属性,得{num1:117,child:undefined}     
 定义变量    obj,之前在栈里的obj     
        

赋值    obj = { num2: 935 },把{ num2: 935 }放在堆里,把栈里的obj指向堆里的{ num2: 935 }     
        

赋值    obj.child = obj,把堆里的 {num1:117,child:undefined} 的child指向  {num2: 935}     
        
    
从最后一张图可看出此时:     
        obj = { num2: 935 }     
        res = { num1: 117,child:{ num2: 935 }  }
发表于 2022-01-21 22:31:57 回复(40)
能写出这种代码的,应该被辞退
发表于 2022-01-29 00:45:03 回复(4)
考察连等赋值。
obj.child = obj = { num2: 935 };
JS引擎在执行赋值语句时,会先从左往右解析各个变量名,转换成变量值,然后从右往左执行赋值。
所以这里首先两个obj都为{ num1: 117 }。
接着从右往左:
obj = { num2: 935 };//第二个等号赋值
{ num1: 117 }.child = { num2: 935 };//第一个等号赋值 
值得注意的是第二个才为真正的obj只有num2。
而第一个obj已经被替换为{ num1: 117 }对象,这个对象中有个child属性,而res又引用了这个对象所以res改变为{ num1:117, child: { num2: 935 } }。

而对var x = y = 935; 同理从右往左执行。可以理解为var x = ( y = 935 );或者y = 935; var x = y;

发表于 2021-12-15 10:06:42 回复(2)
let obj = {
  num1: 117
}
让obj指向{num1:117}
let res = obj;
让res也指向{num1:117}

obj.child = obj = { num2: 935 };
(对于 var a=b=1 这样的代码,只声明第一个变量,不声明后面的,然后从右往左赋值,也就是 var a;b=1;a=b; )
第一步 obj.child,声明obj里的一个属性child,此时 obj.child:undefined;

第二步 obj={num2:935},让obj指向{num2:935}:(obj所指的对象变了)

第三步 obj.child=obj,注意,此时child属性在第一步已经声明过了,这一步只是在给堆内存中的child赋值,也就是让堆内存中的child指向{num2:935};而在第二步中obj的指向已经变了,现在obj里没有child属性,如图:
发表于 2022-03-14 15:46:40 回复(5)
要记住最根本的知识点 给变量赋值一个对象,是将这个对象的地址指向了变量,而不是将对象复制一份给变量
发表于 2022-01-17 20:45:47 回复(0)
JS引擎在执行赋值语句时,先从左往右解析各个变量名,然后从右往左执行赋值。
1、对于 obj.child = obj = { num2: 935 }; 先从左往右解析: obj.child 是{num1 :117} 这个地址引用的对象中取child属性,这个已经确定下来了;然后从右往左赋值:obj的引用地址变为了{num2 : 935},然后{num1:117}.child 的赋值为{num2 : 935};所以 console.log(obj.child)时:obj.child此时拿的时{num2 : 935}.child ,前面说过{num1 :117}有child这个属性,而{num2:935}是没有child这个属性的,所以此时打印obj.child为underfined
2、对于 var x = y = res.child.num2;  先从左往右解析:var x和 y ,然后从右往左赋值:res始终指向{num1:117,child:{num2 :935}},所以y赋值为{num2 : 935},x 也指向 y,所以console.log(res.num1);console.log(y); 两个打印语句的值分别为117和 935




发表于 2022-01-17 11:39:19 回复(0)
基于为什么的第一个值为 undefined, 实际执行过程:从右到左,a 先被赋值为{n:2},随后a.x被赋值{n:2}  但是等值中的两个a的指向 如上图, 所以就容易理解了 等值赋值之后:a={n:2}新的值,而旧的对象被res保存着 res = {a:1, x:{n:2}}   就相当于把a.x的a看作res就好理解了     
发表于 2021-12-21 21:35:12 回复(0)
对象不是指向内存地址的么,为啥不跟着一起变呀
发表于 2022-06-08 12:37:25 回复(1)
连等赋值是什么意思? 
obj.child = obj = { num2: 935 };
可解析为  {num1:117}.child = {num2:935}
{num1:117, child:{num2:935}}

所以答案第一个输出又为什么是undefined呢
发表于 2021-12-17 00:17:52 回复(1)
上一个这么写的应届生已经毕业了
发表于 2022-07-19 15:59:29 回复(0)
我觉着最重要的是知道,只有一条语句执行完后,这条语录中的赋值语句才会生效。
发表于 2022-04-07 16:46:59 回复(0)
真有byd会在业务代码里这么写吗
发表于 2023-02-16 15:52:00 回复(0)
y没有被定义,为什么有值啊😱
发表于 2022-11-20 01:31:13 回复(0)
有点复杂,不动笔脑子有点转不过来
发表于 2022-10-15 16:52:24 回复(0)
先从左往右声明属性,再从右想左赋值
发表于 2022-08-28 10:45:08 回复(0)
Js先从左到右解析变量得到一个具体的变量值,然后从右往左进行赋值
发表于 2022-08-20 16:07:00 回复(0)
JS引擎在执行赋值语句时,会先从左往右解析各个变量名,转换成变量值,然后从右往左执行赋值。
发表于 2022-07-18 14:27:00 回复(0)
赞一个
发表于 2022-06-17 22:06:47 回复(0)
发表于 2022-04-29 11:35:40 回复(0)
先定义变量再赋值
发表于 2022-04-06 14:22:18 回复(0)