2017-08-29 51 views
0

如何解釋這種行爲?爲什麼打印{a:10}?全局對象屬性修改從函數中起作用,但不能重新定義對象本身

var a = {}; 

(function b (a) { 
    a.a = 10; 
    a = null; 
})(a); 

console.log(a); // { a: 10 } 
+0

它不打印'10'它打印'{a:10}'就像你在函數中定義的一樣。哦,你的意思是'null'賦值...... – evolutionxbox

+0

將局部變量'a'改爲別的東西,然後按預期工作。 – evolutionxbox

+1

兩個引用指向同一個對象。當你添加屬性時,它會影響兩個引用,但是當你將它們中的一個設置爲null時,實際上你改變了引用,而不是對象。因此,通過指向對象的原始引用,它會打印10 –

回答

1

在JS返回null,對象是通過引用傳遞。所以當你做()(a)時,你傳遞參考a作爲參數。

現在這個引用保存在局部變量中作爲參數。所以當你更新變量時,你基本上覆蓋了該位置的對象。

訣竅是,當你替換參考。 a=null將更新參數變量a中的引用,但不會覆蓋引用中的對象。所以原始對象仍然可用,只是未被引用。

在IIFE之後,當你再次登錄時,由於自變量的範圍已經結束,它被銷燬,並且a再次指向原始的a

因此,你得到{a: 10}

1

函數內部a是指傳遞給函數的局部變量。既然你選擇了相同的名稱是混亂的,但看到這一點:

var a = {}; 
 

 
(function b (c) { 
 
    console.log('1. c = ', c); 
 
    console.log('2. a = ', a); 
 
    c.a = 10; 
 
    console.log('3. c = ', c); 
 
    console.log('4. a = ', a); 
 
    a = null; 
 
})(a); 
 

 
console.log('5. a = ', a);

它如預期

+0

您可能還希望在分配前後記錄「a」和「c」。 – Bergi

1

a你的函數裏面是比全球a不同的變量。您將全局變量a的值傳入您的函數中,該函數創建一個局部變量。您命名該局部變量a的事實僅僅意味着它以相同的名稱遮蔽全局變量。

所以它是兩個不同的變量,但它們的值都是對您創建的對象的引用。在函數內部寫入該對象的屬性。然後,您將null分配給本地變量a。這隻會刪除對該對象的特定引用,但該對象仍然存在,並且全局變量仍然引用它,因此當您使用此全局變量時,它將打印該對象。

相關問題