Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS 引用相关题目 #18

Open
jirengu opened this issue Dec 28, 2016 · 9 comments
Open

JS 引用相关题目 #18

jirengu opened this issue Dec 28, 2016 · 9 comments

Comments

@jirengu
Copy link
Owner

jirengu commented Dec 28, 2016

以下代码输出什么? 为什么?

var a = {n:1}; 
var b = a;  
a = {n:2}; 
a.x = a ;
console.log(a.x);
console.log(b.x);
var a = {n:1}; 
var b = a;  
a.x = a = {n:2}; 
console.log(a.x);
console.log(b.x);
@jirengu jirengu added this to the 精华题目 milestone Dec 28, 2016
@kevinwulong
Copy link

kevinwulong commented Dec 28, 2016

第二题
.运算符优先于=
1 a.x 变量a和b都有x
2 a={ n:2 } 变量a重新指向到 { n: 2 }
3

a => {n: 2}
b => {n: 1, x: {n: 2 } }

@Jemair
Copy link

Jemair commented Dec 28, 2016

{n: 2, {n: 2, {n: 2, object}}}   //无限循环
undefined                          //在a.x定义时a已经不指向{n :1}这个对象了
undefined                         
{n: 2}           //a.x = a = {n: 2}可以拆分为 a.x = a; a = {n: 2}; 第一句语句给b加上了x属性

@ningxzx
Copy link

ningxzx commented Dec 28, 2016

第一个问题

a.x ---> {n:2,x:a};
b.x ---> undefined;

解答:a的值很清晰了,a第二次赋值以后变成了{n:2},随后添加了x属性指向自身。而对于b,在a第二次赋值以后,由于js中给变量赋值为object类型时,变量中存储的是对这个object的引用。此时,a指向{n:2} ,而b指向了{n:1} ,a和b指向不同的对象,因此,在a上添加属性对于b无影响,b.x自然就是undefined。

第二个问题

a.x ---> undefined ;
b.x ---> {n:2};

解答:第三句里的主要难点在js运算符的优先级,访问属性、调用方法运算符"."的优先级高于赋值运算符。因此执行顺序是

  1. 给a添加属性x,此时a,b都是 { n:1,x:undefined }a.x 运算后的结果即为这个object(可以说也就是b)的x属性值。
  2. 把{n:2}赋值给a,此时a是 {n:2} ,b是{ n:1,x:undefined }。这个时候a.x 已经运算完了,不会再与a产生任何关系,a.x依旧代表那个n为1对象的x属性值,和a已经没关系了。
  3. 把{n:2}赋值给a.x 也就是 { n:1,x:undefined }这个对象的x属性,这个时候b依旧指向这个object,因此此时,a是{n:2},b是{n:1,x:{n:2}}

因此,答案也就一目了然了。

希望面试官不要觉得我话多-。-

@Emma1075
Copy link

这两个问题主要理解两点就很简单了。

  1. 对象是引用类型,改变赋值只是改变指针的引用。运算符=相当于改变指针的指向。
  2. 运算符的优先级. > =。 即:在a.x = a = {n:2};中,先给对象a添加x属性,再进行a={n:2}a.x={n:2}两个赋值操作。

问题1:

// 变量a 指针指向对象 {n:1}
var a = {n:1};  

// 变量b 指针指向对象 {n:1}
var b = a;    

 // 变量b指针不变,仍指向{n:1}; 变量a指针改为指向对象 {n:2}
a = {n:2};   

// 注意运算符的优先级。先给对象a增加x属性,再给x属性赋值。此时x属性的值指向a对象自身。即:a = {n:2,x:a} 
a.x = a ;  

console.log(a.x);  // {n:2,x:a} 

 // 由于b指针没变,还是指向{n:1} ,故b.x: undefined
console.log(b.x);

问题2:

var a = {n:1};

// b与a的指针均指向 {n:1} 
var b = a;  

// 注意运算符优先级`.` > `=`
// 先给a添加x属性。故添加x属性后,a指向的对象{n:1}变为{n:1, x:undefined/待赋值}, 由于b是和a指向的同一个对象,所以此时b={n:1, x:undefined/待赋值}
// 然后再进行赋值操作。a.x = {n:2} ,故x属性的值为{n:2},此时a=b={n:1,x:{n:2}
// 继续赋值操作。 a = {n:2}, a的指针由指向{n:1,x:{n:2} 变为指向对象 {n:2}
a.x = a = {n:2}; 

// 此时a={n:2}, 故a.x为undefined
console.log(a.x);  

// b指针始终没变,b={n:1,x:{n:2}}, 故b.x为{n:2}
console.log(b.x);

@giscafer
Copy link

giscafer commented Dec 28, 2016

指出楼上↓

// 然后再进行赋值操作。a.x = {n:2} ,故x属性的值为{n:2},此时a=b={n:1,x:{n:2}
// 继续赋值操作。 a = {n:2}, a的指针由指向{n:1,x:{n:2} 变为指向对象 {n:2}
a.x = a = {n:2};

a=b=c=1 赋值语句是从右到左的吧。这里感觉你@Emma1075 说的是从左到右。
a = {n:2},后a.x = a

a.x = a = {n:2} 理解

js执行连等赋值语句之前,会取出变量的引用,也就是a.xaa的引用都取出来并保存内存中,执行语句 a.x = a = {n:2}a进行a={n:2}赋值,此时a的引用地址改变指向对象{n:2}从右到左,然后才是是a.x = a 赋值,而a.x的a被取出来的引用和b一样(前面说取出来放内存了),所以a.x = a ,相当于改变b引用的对象的x的属性,所以b.x存的是a的引用,b最终值为{n:1,x:{n:2}}

有对象赋值的时候,尽量不用连等。。

具体看这篇博文,很详细的分析
http://www.jb51.net/article/75496.htm

@450611
Copy link

450611 commented Dec 30, 2016

回复第二题
看楼上几位大大的解答
第二题应该跟第一题一样的吧
a.x = a= {n:2}; ===> a = {n:2}; a.x = a;

拆分开来应该是这样的吧 然后就跟第一题一样了吧
虽然算出的自己运行的结果不是这样的, ,= - =

@giscafer
Copy link

giscafer commented Dec 30, 2016

@450611
连等号赋值不能简单这么拆开,拆开运算和不拆开是两种结果(引用赋值的时候),如果是简单的a=b=c=1你就随便拆开了。

@450611
Copy link

450611 commented Dec 30, 2016

@giscafer
是不是
a.x = a;
a ={n:2}

这样拆的?

@Amorcy
Copy link

Amorcy commented Jan 4, 2017

第二题
var a = {n:1};
var b = a;
a.x= a = {n:2}; //相当于a.x=a; a={n:2} 首先给a.x赋值为a(此时a的引用还是{n:1}),而后给a重现指向另外一个引用{n:2}, //而这个引用中只有n这一个属性,找不到a这个属性,所以:a.x为undefined,b=a={n:2} console.log(a.x); //undefined
console.log(b.x); //{n:2}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants