關於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時,這個變量引用的就是一個局部對象了。而這個局部對象會在函數執行完畢後當即被銷燬。學習

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

然而,咱們能夠確定的是:當一個引用類型的對象不是當作參數傳遞時,它是按引用傳遞的。code

咱們來看另一個例子:對象

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當作參數傳遞的狀況是同樣的。能夠肯定的是:這個例子中對象是按引用傳遞的。但按照尼古拉的說法這個例子中對象也是按值傳遞的。 那麼能夠得出結論:尼古拉的說法是錯的。blog

咱們可用圖來講明一下這個問題。ip

var person = new Object()時,能夠用下面這幅圖來描述變量和對象之間的關係:作用域

var obj = person時,能夠用下面這幅圖來描述它們之間的關係:開發

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

咱們能夠把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中,對象不管是否是當成參數傳遞,都是按引用傳遞的。固然這僅是我我的得出的結論,若是你們有不一樣的見解,很是願意向你們學習。

相關文章
相關標籤/搜索