javascript中的變量是傳值還是傳址的?
更新時間:2010年04月19日 21:39:03 作者:
一門編程語言的核心是數(shù)據(jù)結(jié)構(gòu),粗略來講,可以把數(shù)據(jù)結(jié)構(gòu)分成不可變類型(immutable)和可變類型(mutable)。
這個標題念起來有點拗口,但卻是理解數(shù)據(jù)結(jié)構(gòu)的關(guān)鍵。標題中的4個術(shù)語,對應(yīng)的英文分別是:shallow copy(注意,不是shadow copy)、deep copy、pass by value、pass by reference(或pass by address)。傳址和傳引用是一回事。
一門編程語言的核心是數(shù)據(jù)結(jié)構(gòu),粗略來講,可以把數(shù)據(jù)結(jié)構(gòu)分成不可變類型(immutable)和可變類型(mutable)。為什么這么分呢?這涉及到內(nèi)存分配問題。對于不可變類型,只要分配有限的內(nèi)存空間即可,而對于不可變類型,理論上則要分配沒有大小限制的空間。因此,這么分是出于合理利用系統(tǒng)資源的考慮。實際上,堆內(nèi)存和棧內(nèi)存分別用于保存不可變類型值和可變類型值。
什么是不可變類型?就是該值一旦賦予某個變量,就只屬于某個變量,不能同屬于其他變量。如:
window.onload=function()
{
var stringValue = "淡淡的";
var anotherStringValue = stringValue;
stringValue = "I have changed";
alert(stringValue);// 輸出 I have changed
alert(anotherStringValue);// 輸出 淡淡的
此時,anotherStringValue中保存的值會不會也變成“I have changed”?不會。因為
var anotherStringValue = stringValue;
照stringValue中保存的字符串的原樣,復(fù)制一個字符串(相應(yīng)地,在內(nèi)存中分配一塊新空間),并將該字符串賦給anotherStringValue。換句話說,這兩個變量雖然保存的值相同,但它們的值并不在一塊內(nèi)存中。因此,修改任何一個變量,都不會影響另一個變量。即
stringValue = “I have changed”;
只會影響stringValue的值。但是,確切來講,stringValue = “I have changed”;并不是修改stringValue,而是創(chuàng)建了一個新字符串(相應(yīng)地,在內(nèi)存中分配一塊新空間),然后讓stringValue引用該字符串——更像是替換變量的值;原來的字符串呢?因為沒有變量引用它,也就成為垃圾了(當然,垃圾所占用的內(nèi)存會被回收)。
由此可見,賦值操作對于不變類型而言,傳遞的是內(nèi)存中的值本身。那么,對于可變類型呢?當然,傳遞的是內(nèi)存中值的引用(或者說地址),而且無論傳遞多少次,內(nèi)存中始終都只有一份原始值——畢竟可變類型大小莫測,只保存一份原始值能最大限度節(jié)省內(nèi)存空間。例如:
window.onload=function()
{
var objectValue = {1:1,'s':'string','innerObject':{'innerArray' : [1,2,3]}};
var anotherObjectValue = objectValue;
objectValue[1] = 100;
alert(anotherObjectValue[1]); //輸出 100
}
不言自明,這里的anotherObjectValue通過賦值操作,從objectValue那里只獲得了對原始對象( {1:1,'s':'string','innerObject':{'innerArray' : [1,2,3]}})的引用,也就是該對象在內(nèi)存中的地址,或者說“門牌號碼”。因此,通過objectValue修改原始對象的第一個元素(objectValue[1] = 100;),結(jié)果同樣會在anotherObjectValue[1]那里得到反映——因為這兩個變量共享同一份原始值。
在JavaScript中,給函數(shù)傳遞參數(shù)是按照上述默認約定——即對不可變類型,傳值;對可變類型,傳址——進行的。如:
function example(str, obj){
……
}
example(stringValue,objectValue);
調(diào)用example函數(shù)時,第一個參數(shù)傳遞的是實際的字符串值,第二參數(shù)傳遞的是對象的引用(內(nèi)存地址)。
一門編程語言的核心是數(shù)據(jù)結(jié)構(gòu),粗略來講,可以把數(shù)據(jù)結(jié)構(gòu)分成不可變類型(immutable)和可變類型(mutable)。為什么這么分呢?這涉及到內(nèi)存分配問題。對于不可變類型,只要分配有限的內(nèi)存空間即可,而對于不可變類型,理論上則要分配沒有大小限制的空間。因此,這么分是出于合理利用系統(tǒng)資源的考慮。實際上,堆內(nèi)存和棧內(nèi)存分別用于保存不可變類型值和可變類型值。
什么是不可變類型?就是該值一旦賦予某個變量,就只屬于某個變量,不能同屬于其他變量。如:
復(fù)制代碼 代碼如下:
window.onload=function()
{
var stringValue = "淡淡的";
var anotherStringValue = stringValue;
stringValue = "I have changed";
alert(stringValue);// 輸出 I have changed
alert(anotherStringValue);// 輸出 淡淡的
此時,anotherStringValue中保存的值會不會也變成“I have changed”?不會。因為
var anotherStringValue = stringValue;
照stringValue中保存的字符串的原樣,復(fù)制一個字符串(相應(yīng)地,在內(nèi)存中分配一塊新空間),并將該字符串賦給anotherStringValue。換句話說,這兩個變量雖然保存的值相同,但它們的值并不在一塊內(nèi)存中。因此,修改任何一個變量,都不會影響另一個變量。即
stringValue = “I have changed”;
只會影響stringValue的值。但是,確切來講,stringValue = “I have changed”;并不是修改stringValue,而是創(chuàng)建了一個新字符串(相應(yīng)地,在內(nèi)存中分配一塊新空間),然后讓stringValue引用該字符串——更像是替換變量的值;原來的字符串呢?因為沒有變量引用它,也就成為垃圾了(當然,垃圾所占用的內(nèi)存會被回收)。
由此可見,賦值操作對于不變類型而言,傳遞的是內(nèi)存中的值本身。那么,對于可變類型呢?當然,傳遞的是內(nèi)存中值的引用(或者說地址),而且無論傳遞多少次,內(nèi)存中始終都只有一份原始值——畢竟可變類型大小莫測,只保存一份原始值能最大限度節(jié)省內(nèi)存空間。例如:
復(fù)制代碼 代碼如下:
window.onload=function()
{
var objectValue = {1:1,'s':'string','innerObject':{'innerArray' : [1,2,3]}};
var anotherObjectValue = objectValue;
objectValue[1] = 100;
alert(anotherObjectValue[1]); //輸出 100
}
不言自明,這里的anotherObjectValue通過賦值操作,從objectValue那里只獲得了對原始對象( {1:1,'s':'string','innerObject':{'innerArray' : [1,2,3]}})的引用,也就是該對象在內(nèi)存中的地址,或者說“門牌號碼”。因此,通過objectValue修改原始對象的第一個元素(objectValue[1] = 100;),結(jié)果同樣會在anotherObjectValue[1]那里得到反映——因為這兩個變量共享同一份原始值。
在JavaScript中,給函數(shù)傳遞參數(shù)是按照上述默認約定——即對不可變類型,傳值;對可變類型,傳址——進行的。如:
function example(str, obj){
……
}
example(stringValue,objectValue);
調(diào)用example函數(shù)時,第一個參數(shù)傳遞的是實際的字符串值,第二參數(shù)傳遞的是對象的引用(內(nèi)存地址)。
相關(guān)文章
javascript算法學(xué)習(xí)(直接插入排序)
假設(shè)待排序的記錄存放在數(shù)組R[1..n]中。初始時,R[1]自成1個有序區(qū),無序區(qū)為R[2..n]。從i=2起直至i=n為止,依次將R[i]插入當前的有序區(qū)R[1..i-1]中,生成含n個記錄的有序區(qū)。2011-04-04H5如何實現(xiàn)喚起APP及調(diào)試bug解決
這篇文章主要為大家介紹了H5如何實現(xiàn)喚起APP及調(diào)試bug解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05JavaScript function 的 length 屬性使用介紹
函數(shù)的 length 得到的是形參個數(shù),如果函數(shù)內(nèi)部是通過arguments 調(diào)用參數(shù),而沒有實際定義參數(shù)的話, length 只會的得到02014-09-09iscroll動態(tài)加載數(shù)據(jù)完美解決方法
這篇文章主要為大家詳細介紹了iscroll動態(tài)加載數(shù)據(jù)的完美解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07使用requirejs模塊化開發(fā)多頁面一個入口js的使用方式
這篇文章主要介紹了使用requirejs模塊化開發(fā)多頁面一個入口js的使用方式,需要的朋友可以參考下2017-06-06