在《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
當成一箇中間人,它是聯繫person
與obj
的橋樑。之因此改變obj
的屬性值,會影響person
實際上是經過Object
來傳遞的。當obj = new Object()
,這時obj
與Object
之間的關係徹底斷開,與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中,對象不管是否是當成參數傳遞,都是按引用傳遞的。固然這僅是我我的得出的結論,若是你們有不一樣的見解,很是願意向你們學習。