这篇文章会配合Excel表来说明传值、传参考的特性喔!
传值
以上一篇文章的範例来说
var person = '小明';var person2 = person;
person2 = '杰伦';
传参考
var person = { name: '小明'};var person2 = person;
person2.name = '杰伦';
那么我们再来看看下面的例子~
var family = { name: '小明家', members: { father: '老爸', mom: '老妈', ming: '小明' }};var member = family.members;member.ming = '大明';console.log(member, family.members)
很明显这也是一个传参考的例子,根据上篇文章的知识我们可以知道
console.log(member, family.members)
印出来的结果 不论是 member.ming
还是 family.members.ming
都会被改成 大明,就是因为 member 被赋予的是family.members这个物件的记忆体位置。
我们再以 excel 的方式来说明~
就会像是这样的感觉~
所以如果今天把它改成大明的话
member.ming = '大明';
接着来一些难一点的观念喔!
看看程式码吧~!
var a = { x: 1 };a.y = a;console.log(a);
可以看到首先先物件实字定义了 var a = { x: 1 };
再定义 物件 a 里面有一个 y 的属性,并且把 a 他自己赋值(传参考)到 y 这个属性上。
最后在印出来看看 a 长怎样
重点就是~各位会觉得发生甚么事情呢?
我们来看看~
感觉好像打开俄罗斯娃娃,一直都是一样的内容~
好~我们一样来用 excel 讲解这个原理喔~!
我们就可以看到,如果今天要找 a 里面的 y 的话,他又会找到 0x01 的自己,造成无限的循环。
这个特别的例子也其实是要强化各位对于 传参考 这件事情的感觉。
那我们再来看看其他範例~
var a = { x: 1};var b = a;a.y = a = { x: 2 };console.log(a.y);console.log(b);
首先我们一样定义了 var a = { x: 1};
,并且定义 b 将 a 的参考(记忆体位置)传给他。
最后定义新的物件{ x: 2 }并且重新赋值到 a 以及 a.y 上面
然后印出 a.y 以及 b
大家可以先想看看结果可能会是甚么喔
答案如上,a.y 是 undefined,那么 a 呢?
我们可以再找看看 a 是多少~
他回传我 a = {x: 2}
好~那到这里~我们一样再用 excel 表解释这一切的来龙去脉!
var a = { x: 1};
var b = a;
好~到这一段应该没甚么问题~
再来看看重头戏!
a.y = a = { x: 2 };
这边有三个重点
a = { x: 2 }
的回传值是 { x: 2 }
, 所以不论是 a 还是 a.y 都会被赋值(传参考) { x: 2 }
的参考。所以可以也可以等同于 a = a.y = { x: 2 };
a.y = a = { x: 2 };
是同时执行的!!因此没有执行顺序的问题,也就是没有因为 a
的参考先被转成了 0x02 才进行 a.y
的赋值,没有喔!!是同时的,所以 a.y
才会是找原本的参考(0x01)
a.y
找的是原本的参考(0x01),而不是后来的参考(0x02)所以这里 a.y
的赋值是在原本的参考(0x01)
最后的结果就如上图,所以我们利用 console.log(a.y)
以及 console.log(b)
会发现
a 现在指向的是 0x02的物件,但里面没有 y 所以是 undefined
b 则是指向了原本 0x01 的物件,所以就照实显示里面的内容
所以如果我们用
console.log(a === b.y); // true
会得到的结果也是 true 的结果喔!
透过上面这些範例,了解传参考的过程是如何运行的
总结一下重点:
连续赋值的时候会是同时执行,不会分优先顺序回传值的内容(运算子的章节有介绍过)参考值互换的话,寻找的参考是原本的参考值那么可以依照上面讲述的观念~大家来看看下面的题目
var a = { x: 1};var b = a;a.x = { x: 2};a.y = a = { y: 1};console.log(a); // 结果?console.log(b); // 结果?
也可以利用 excel 的拆解方式~回答这个题目喔~答案公布在留言处
以上就是本章节的介绍,希望对各位有帮助~汪汪