JavaScript數(shù)據(jù)操作_淺談原始值和引用值的操作本質(zhì)
我的一句話總結(jié):原始值不管是變量賦值還是函數(shù)傳遞都不會(huì)改變?cè)担弥挡还苁亲兞抠x值還是函數(shù)傳遞,如果新變量重新賦值,則不會(huì)影響原引用值,如新變量是直接操作,就會(huì)影響原引用值。
首先明確,值和類型是兩個(gè)不同的概念。例如,null是null類型的唯一值、undefined是undefined類型的唯一值、而true和false是boolean類型僅有的兩個(gè)值等。在任何語(yǔ)言中,值的操作都可以歸納為以下3個(gè)方面。
復(fù)制值:即把值賦值給新變量,或者通過(guò)變量把值賦值給另一個(gè)變量、屬性或數(shù)組元素。
傳遞值:即把值作為參數(shù)傳遞給函數(shù)或方法。
比較值:即把值與另一個(gè)值進(jìn)行比較,看是否相等。
由于值類型數(shù)據(jù)和引用型數(shù)據(jù)的值存在形式不同,自然操作它們的方法和所產(chǎn)生的結(jié)果也是不同的。注意,當(dāng)值為值類型數(shù)據(jù)時(shí),我們常稱之為原始值或基本值;當(dāng)值為引用型數(shù)據(jù)時(shí),我們常稱之為引用值或復(fù)合值。
1.使用原始值
對(duì)于原始值來(lái)說(shuō),其操作的3個(gè)層面說(shuō)明如下。
1)復(fù)制值
在賦值語(yǔ)句中,操作的過(guò)程將會(huì)產(chǎn)生一個(gè)實(shí)際值的副本,副本的值和實(shí)際值之間沒(méi)有任何聯(lián)系,它們獨(dú)自位于不同的棧區(qū)或者堆區(qū)。這個(gè)副本可以存儲(chǔ)變量、對(duì)象的屬性和數(shù)組的元素。例如:
var n = 123, a, b = [], c = {}; a = n; // 復(fù)制數(shù)字123 b[0] = n; // 復(fù)制數(shù)字123 c.x = n; // 復(fù)制數(shù)字123 (a == b[0]) && (a == c.x) && (b[0] == c.x) && alert("復(fù)制的值都是相等的"); // 檢測(cè)它們的值都是相等的
在上面示例中,分別把值123復(fù)制3份給變量a、數(shù)組b和對(duì)象c,雖然它們的值是相等的,但是它們之間是相互獨(dú)立的。
2)傳遞值
當(dāng)把值傳遞給函數(shù)或方法時(shí),傳遞的值僅是副本,而不是值本身。例如,如果在函數(shù)中修改傳遞進(jìn)來(lái)的值時(shí),結(jié)果只能夠影響這個(gè)參數(shù)值的副本,并不會(huì)影響到原來(lái)的值。
var a = 123; // 原來(lái)的值 function f(x){ x = x + x; } f(a); // 調(diào)用函數(shù)修改傳遞的值 alert(a); // 查看變量a的值是否受影響,返回值為123,說(shuō)明沒(méi)有變化
3)比較值
在上面的示例中我們也可以看到,當(dāng)對(duì)原始值進(jìn)行比較時(shí),進(jìn)行逐字節(jié)的比較來(lái)判斷它們是否相等。比較的是值本身,而不是值所處的位置,固然比較的結(jié)果可能會(huì)相等,但只是說(shuō)明它們所包含的字節(jié)信息是相同的。
2.使用引用值
對(duì)于引用值來(lái)說(shuō),其操作的3個(gè)層面說(shuō)明如下。
1)復(fù)制值
在賦值語(yǔ)句中,所賦的值是對(duì)原值的引用,而不是原值副本,更不是原值本身。也就是說(shuō),進(jìn)行賦值之后,變量保存的都是對(duì)原值的引用(即原值的存儲(chǔ)地址)。當(dāng)在多個(gè)變量、數(shù)組元素或?qū)ο髮傩灾虚g復(fù)制時(shí),它們都會(huì)與原始變量保存的引用相同。
所有引用具有相同的效力和功能,都可以執(zhí)行操作,如果通過(guò)其中的一個(gè)引用編輯數(shù)據(jù),這種修改將會(huì)在原值及其他相關(guān)引用中體現(xiàn)出來(lái)。例如:
var a = [1,2,3]; // 賦值數(shù)組引用 b = a; // 復(fù)制值 b[0] = 4; // 修改變量b中第一個(gè)元素的值 alert(a[0]); // 返回4,顯示變量a中第一個(gè)元素的值也被修改為4
但是,如果給變量b重新賦予新值,則新值不會(huì)影響原值內(nèi)容。例如:
var a = [1,2,3]; // 賦值數(shù)組引用 b = a; // 復(fù)制值 b = 4; // 為變量b重寫賦值 alert(a[0]); // 變量a的內(nèi)容保持不變
重復(fù)賦值實(shí)際上是覆蓋變量對(duì)原值的引用,變?yōu)榱硪粋€(gè)值的副本或?qū)ζ湟谩K圆粫?huì)對(duì)原值產(chǎn)生影響,演示示意圖如圖4-2所示。
2)傳遞值
當(dāng)使用引用將數(shù)據(jù)傳遞給函數(shù)時(shí),傳遞給函數(shù)的也是對(duì)原值的一個(gè)引用,函數(shù)可以使用這個(gè)引用來(lái)修改原值本身,任何修改在函數(shù)外部都是可見(jiàn)的。例如:
var a = [1,2,3]; function f(x){ x[0] = 4; // 在函數(shù)中修改參數(shù)值 } f(a); // 傳遞引用值 alert(a[0]); // 返回4,原值發(fā)生變化
請(qǐng)注意,在函數(shù)內(nèi)修改的是對(duì)外部對(duì)象或數(shù)組的引用,而不是對(duì)象或數(shù)組本身的值。在函數(shù)內(nèi)可以使用引用來(lái)修改對(duì)象的屬性或數(shù)組的元素,但是如果在函數(shù)內(nèi)部使用一個(gè)新的引用覆蓋原來(lái)的引用,那么在函數(shù)內(nèi)部的修改就不會(huì)影響原引用的值,函數(shù)外部也是看不到的。
var a = [1,2,3]; function f(x){ x = 4; // 在函數(shù)中修改參數(shù)值 } f(a); // 傳遞引用值 alert(a[0]); // 返回1,原值不會(huì)發(fā)生變化
3)比較值
當(dāng)比較兩個(gè)引用值時(shí),比較的是兩個(gè)引用地址,看它們引用的原值是否為同一個(gè)副本,而不是比較它們的原值字節(jié)是否相等。當(dāng)對(duì)兩個(gè)不同值進(jìn)行引用時(shí),盡管它們具有相同的字節(jié)構(gòu)成,但是這兩個(gè)引用的值卻是不相等的。
var a = new Number(1); // 引用值a var b = new Number(1); // 引用值b var c = a; // 把a(bǔ)的引用賦值給c alert(a==b); // 返回false alert(a==c); // 返回true
所以,{} == {},[] == [],都返回false。因?yàn)橐玫刂凡煌?/p>
總之,對(duì)于任何語(yǔ)言來(lái)說(shuō),使用值和使用引用都是數(shù)據(jù)操作的兩種基本方法。當(dāng)我們操作數(shù)據(jù)時(shí),要采用什么方法來(lái)進(jìn)行處理,主要看數(shù)據(jù)的類型。值類型和引用型數(shù)據(jù)參與運(yùn)算的方式不同,值類型數(shù)據(jù)通過(guò)使用值來(lái)操作數(shù)據(jù),而引用型數(shù)據(jù)使用引用來(lái)操作數(shù)據(jù)。運(yùn)算方式的不同,自然所產(chǎn)生的結(jié)果也不同。我們不妨再看一個(gè)示例:
var s = "abc"; // 字符串,值類型數(shù)據(jù) var o = new String(s); // 字符串對(duì)象,被裝箱后的字符串 function f(v){ // 運(yùn)算函數(shù) v.toString = function(){ // 修改參數(shù)的方法toString() return 123; }; } f(s); // 傳入值 alert(s); // 返回字符串"abc",說(shuō)明運(yùn)算沒(méi)有對(duì)原數(shù)據(jù)造成影響 f(o); // 傳入引用 alert(o); // 返回?cái)?shù)值123,說(shuō)明運(yùn)算已經(jīng)影響到原數(shù)據(jù)的內(nèi)部結(jié)構(gòu)
值類型是以實(shí)際值參與運(yùn)算的,因此與原數(shù)據(jù)沒(méi)有直接聯(lián)系。而引用型以引用地址參與運(yùn)算,計(jì)算的結(jié)果會(huì)影響到引用地址所關(guān)聯(lián)的堆區(qū)數(shù)據(jù)塊。但是,有一點(diǎn)例外,對(duì)于JavaScript的字符串來(lái)說(shuō),它的操作方法就比較復(fù)雜,詳情請(qǐng)google!
以上這篇JavaScript數(shù)據(jù)操作_淺談原始值和引用值的操作本質(zhì)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
javascript實(shí)現(xiàn)仿銀行密碼輸入框效果的代碼
這篇文章通過(guò)實(shí)例代碼給大家介紹了javascript實(shí)現(xiàn)仿銀行密碼輸入框效果,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2007-12-12JavaScript使用FileSystemObject對(duì)象寫入文本文件內(nèi)容的方法
這篇文章主要介紹了JavaScript使用FileSystemObject對(duì)象寫入文本文件內(nèi)容的方法,實(shí)例分析了javascript使用ActiveXObject的技巧與常見(jiàn)問(wèn)題的解決方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08在Postman的腳本中如何使用pm對(duì)象獲取接口的請(qǐng)求參數(shù)
這篇文章主要介紹了在Postman的腳本中如何使用pm對(duì)象獲取接口的請(qǐng)求參數(shù),本文通過(guò)實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09JS信息收集代碼研究(獲取客戶端的瀏覽器、cpu等軟硬件信息)
聽(tīng)朋友說(shuō),這段JavaScript信息收集代碼主要用于收集IP......等等什么的,用來(lái)研究,需要的朋友可以參考一下2023-06-06JavaScript canvas實(shí)現(xiàn)動(dòng)態(tài)點(diǎn)線效果
這篇文章主要為大家詳細(xì)介紹了JavaScript canvas實(shí)現(xiàn)動(dòng)態(tài)點(diǎn)線效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08基于javascript實(shí)現(xiàn)圖片切換效果
這篇文章主要介紹了基于javascript實(shí)現(xiàn)圖片切換效果的相關(guān)資料,需要的朋友可以參考下2016-04-04

Js通過(guò)AES加密后PHP用Openssl解密的方法