2016-05-16 15 views
0
var a = 1; 

function x() { 
    a = 2 
    console.log(a) // 2 
} 
x(); 

console.log(a); // 2 

和:這兩個關於JavaScript範圍鏈的例子有什麼區別?

var a = 1; 

function x(p) { 
    p = 2 
    console.log(p) // 2 
} 
x(a); 

console.log(a); // 1 

爲什麼是第二示例1而不是2的輸出?

+1

[只有值作爲參數傳遞。](http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) ,'p'與'a'沒有關係,只有值'1',然後到'2'。 –

回答

2

這是因爲您的p變量只存在於function x(p)之內。所以,你在內存中有一個新的空間,一個複製變量a。在第一個例子中,它是一個指向變量a的內存地址的指針。

在另一方面,對象具有「按引用傳遞」,所以,如果你這樣做:

var obj = { foo: 1 }; 

function x(paramObj) { 
    paramObj.foo = "2"; 
} 

x(obj); 
alert(obj.foo); 

你會看到「2」,而不是「1」。

+0

您的示例工作正常,但沒有必要將'obj'作爲參數傳遞給'x()' – Marcus

+0

您是對的,所以我編輯以使其更有意義。代碼使用了相同的參數名稱,現在它顯示了我的觀點。 –

0

因爲當函數執行時函數參數是'創建'的。

var a = 1; 

function x(p) { 
    p = 2 
    console.log(p) // 2 
}; 

在這段代碼中你創建了全局變量a = 1;然後你將它傳遞給x函數。在函數內部,您將給定的參數設置爲2並將其設置爲console.log;但真正發生的是:

var a = 1; 


function x(given_argument) { 
    var p = given_argument; 
    p = 2; // global a variable still equals 1; 
    console.log(p) // 2 
}; 

這是因爲Javascript中有兩種類型的變量。像數字,字符串,布爾等數值,只是值和數組,對象等參考類型。

如果你瞭解C++,那麼這應該會讓事情變得更輕鬆。這是相當於在Javascript中發生了什麼,寫在C++:

// javascript 
var a = 1; // plain value 

// c++ 
int a = 1; // plain value 

// javascript 
var a = {}; // referential type, this is a pointer behind the scenes 
// or 
var a = new Object(); // if you prefer it this way 

// c++ 
Object* a = new Object(); // this is a pointer to the object, but in C++ you make it a pointer explicitly, in Javascript this happens 'automagically'. 

參照類型的Javascript是指針,這意味着他們可以從內部功能被改變,如果作爲參數傳遞。但是如果你像數字或布爾值那樣傳遞正常值,它就會在函數內部聲明,並且它隱含地發生。

我希望它澄清了這個問題。