節(jié)前,沒了靈魂的伙,在學(xué)習(xí)值和引用之間的區(qū)別
在JavaScript中,可以通過值和引用傳遞。兩者之間的主要區(qū)別是,按值傳遞發(fā)生在賦值基本類型的時(shí)候,而賦值對(duì)象時(shí)按引用傳遞。接下來,跟著智哥,來詳細(xì)看看。
1.理解基本類型和對(duì)象
JavaScript提供了2種數(shù)據(jù)類型:基本類型和對(duì)象。
基本類型有 number, boolean, string, symbol,null,undefined。
- // 基本類型
- const number = 10;
- const bool = false;
- const str = 'Hello!';
- const missingObject = null;
- const nothing = undefined;
第二類是對(duì)象,普通對(duì)象、數(shù)組、函數(shù)等等都是對(duì)象。
- // Objects
- const plainObject = {
- prop: 'Value'
- };
- const array = [1, 5, 6];
- const functionObject = (n1, n2) => {
- return n1 + n2;
- };
換句話說,任何不是基本類型的值都是對(duì)象。
2.值
按值傳遞的簡(jiǎn)單規(guī)則是 JS 中的所有基本類型都按值傳遞,就這么簡(jiǎn)單。
按值傳遞意味著每次將值賦給變量時(shí),都會(huì)創(chuàng)建該值的副本,每一次哦。
舉個(gè)例子來看看,假設(shè)我們有兩個(gè)變量 a 和 b:
- let a = 1;
- let b = a;
- b = b + 2;
- console.log(a); // 1
- console.log(b); // 3
第一條語句,聲明一個(gè)變量 a,并賦值為 1。
第二條語句,聲明一個(gè)變量 b,并把 a 的值賦值給它。
最后,b = b + 2增加2并變?yōu)?。b變量發(fā)生變化,并且該變化不會(huì)影響a的值。
3.引用
通過引用傳遞的方式與值傳遞相比會(huì)有所不同。
當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí),就獲取一個(gè)對(duì)該對(duì)象的引用。如果兩個(gè)變量持有相同的引用,那么改變對(duì)象會(huì)反映在兩個(gè)變量中。
請(qǐng)看下面代碼:
- let y = x;
- y.push(2);
- console.log(x); // [1, 2]
- console.log(y); // [1, 2]
第一個(gè)語句let x =[1]創(chuàng)建一個(gè)數(shù)組,定義一個(gè)變量x,并使用對(duì)創(chuàng)建的數(shù)組的引用來初始化變量。
然后let y = x定義一個(gè)變量y,并使用存儲(chǔ)在x變量中的引用來初始化y,這是一個(gè)引用傳遞。
y通過y.push(2)通來改變數(shù)組。因?yàn)閤和y變量引用相同的數(shù)組,所以這種變化會(huì)反映在兩個(gè)變量中。
注意:為簡(jiǎn)單起見,我說變量包含對(duì)對(duì)象的引用。但是嚴(yán)格說來,JavaScript中的變量包含的值是對(duì)對(duì)象的引用。
4.值的比較和引用的比較
在比較對(duì)象時(shí),理解值和引用之間的區(qū)別非常重要。
當(dāng)使用嚴(yán)格比較運(yùn)算符===時(shí),如果兩個(gè)變量的值相同,則它們相等。以下所有比較均相等
- const one = 1;
- const oneCopy = 1;
- console.log(one === oneCopy); // true
- console.log(one === 1); // true
- console.log(one === one); // true
one和oneCopy具有相同的值1。當(dāng)兩個(gè)操作數(shù)都為1時(shí),操作符===的計(jì)算結(jié)果都為true。
但是比較運(yùn)算符===在比較引用時(shí)的工作方式有所不同。2個(gè)引用只有在引用完全相同的對(duì)象時(shí)才相等。
ar1和ar2保存對(duì)不同數(shù)組實(shí)例的引用:
- const ar1 = [1];
- const ar2 = [1];
- console.log(ar1 === ar2); // false
- console.log(ar1 === [1]); // false
- const ar11 = ar1;
- console.log(ar1 === ar11); // true
- console.log(ar1 === ar1); // true
ar1和ar2引用結(jié)構(gòu)相同的數(shù)組,但是ar1 === ar2的計(jì)算結(jié)果為false,因?yàn)閍r1和ar2引用了不同的數(shù)組對(duì)象。
僅當(dāng)比較指向相同對(duì)象的引用時(shí),比較運(yùn)算符才返回true:ar1 === ar11或ar1 === ar1。
5.總結(jié)
在JavaScript中,原始類型作為值傳遞:意味著每次分配值時(shí),都會(huì)創(chuàng)建該值的副本。
另一方面,對(duì)象(包括普通對(duì)象,數(shù)組,函數(shù),類實(shí)例)是引用。如果修改對(duì)象,則引用該對(duì)象的所有變量都將看到更改。
比較運(yùn)算符區(qū)分比較值和參考。僅當(dāng)引用完全相同的對(duì)象時(shí),2個(gè)保存引用的變量才相等,但是,無論值源自何處,只要變量具有相同的2個(gè)值(分別來自變量,文字等),則2個(gè)保存值的變量就相等。
~ 完,我是刷碗智,我們下期見!
作者:Ahmad shaded 譯者:前端小智 來源:sitepoint原文:https://dmitripavlutin.com/value-vs-reference-javascript/