關於js中一個對象當做參數傳遞是按值傳遞還是按引用傳遞的個人看法


在《JavaScript高級程序設計》這本書中有這樣一段話:有很多開發人員錯誤的認為:在局部作用域中修改的對象會在全局作用域中反映出來,就說明參數是按引用傳遞的。換句話說,尼古拉認為當一個對象是當做參數傳遞時,它是按值傳遞的。然后他舉了個例子來證明這個結論:

function setName(obj) {
  obj.name = "Nicholas";
  obj = new Object();
  obj.name = "Greg";	
}

var person = new Object();
setName(person);
alert(person.name); // "Nicholas"

他解釋到:如果person是按引用傳遞的,那么person就會自動被修改為指向其name屬性值為"Greg"的新對象。但是,當接下來再訪問person.name時,顯示的值任然是"Nicholas"。這說明即使在函數內部修改了參數的值,但原始的引用任然保持不變。實際上,當在函數內部重寫obj時,這個變量引用的就是一個局部對象了。而這個局部對象會在函數執行完畢后立即被銷毀。

從上面的例子中,尼古拉得出的結論是:當一個對象當做參數傳遞時,它是按值傳遞的。

然而,我們可以肯定的是:當一個引用類型的對象不是當做參數傳遞時,它是按引用傳遞的。

我們來看另外一個例子:

var person = new Object();
var obj = person;
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
alert(person.name); // "Nicholas"

這個例子中person對象不是當做參數傳遞的,但person.name的值還是"Nicholas",這和person當做參數傳遞的情況是一樣的。可以確定的是:這個例子中對象是按引用傳遞的。但按照尼古拉的說法這個例子中對象也是按值傳遞的。 那么可以得出結論:尼古拉的說法是錯的。

我們可用圖來說明一下這個問題。

var person = new Object()時,可以用下面這幅圖來描述變量和對象之間的關系:

var obj = person時,可以用下面這幅圖來描述它們之間的關系:

obj = new Object()時,用下面的圖描述它們的關系:

我們可以把Object當成一個中間人,它是聯系personobj的橋梁。之所以改變obj的屬性值,會影響person其實是通過Object來傳遞的。當obj = new Object(),這時objObject之間的關系完全斷開,與new Object建立了關系。當obj.name = "Greg",此時,obj"Object"之間已沒有關系,當然不會再影響"Object"

書中的例子是一樣的道理:

function setName(obj) {
  obj.name = "Nicholas";
  obj = new Object();
  obj.name = "Greg";	
}

var person = new Object();
setName(person);
alert(person.name); // "Nicholas"

obj相當於setName函數中的一個局部變量,把person傳給函數就相當於var obj = person。其實我們完全可以把這個例子和上面介紹的那個例子看成是等價的,所以上面的圖解也適用這個例子。

上面通過例子來說明尼古拉的結論是錯的,從而得出自己的結論:ECMAScript中,對象無論是不是當成參數傳遞,都是按引用傳遞的。當然這僅是我個人得出的結論,如果大家有不同的看法,非常願意向大家學習。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM