2014-01-14 189 views
3

我一直在觀看道格拉斯克羅克福德的視頻系列。我對將變量賦值爲一個將變量賦值爲全局變量的參數的關係有點困惑,讓我來演示一下。變量與參數範圍和賦值

var bob = 22; //global scope 
function funky(parameter){ 
    parameter = null; //sets the var passed in to null 
    bob = 44; //sets the bob 
} 

var hello = []; 
funky(hello); // hello still has the value of an empty array even after the function is invoked. 
bob; // value is 44 

因此,當funky()被調用時,'var bob'被賦值44。這個鮑勃擁有超出功能範圍的新價值。

var hello作爲一個參數傳遞,而funky裏面,它的值爲null,當hello在全局空間被調用時,它的值爲空,它包含一個空數組的值。

這是我必須背誦的東西嗎?如果將全局作用域中的已定義變量作爲參數傳遞,它將只在該函數的作用域內保存新的已分配值?我是否在更廣泛的範圍內缺少某些參數如何傳遞和分配給函數?

這裏是代碼的repl.it與console.log輸出,而在函數/全局作用域內部和外部。

http://repl.it/NgN

+2

一時間,覺得你會想怎麼回事,這個工作?你越想回答這個問題,你就會意識到這是它應該如何工作,然後你就會理解這個模式,而且你不必再記住了! – Kiran

+1

此外,全局變差。避免它們! – m59

+0

其他人會糾正我,如果我錯了,但從技術上講,'bob'不是全局的,因爲它沒有被添加到全局對象(通常是'window')。這只是一個非局部變量。當'funky'引用'bob'時,JavaScript會創建一個[closure](http://en.wikipedia.org/wiki/Closure_(computer_programming)),它允許函數訪問該變量。 –

回答

3

因爲該行

parameter = null; 

只設置功能的參數的值,中傳遞的變量不是值。然而,bob函數內部interpretted爲對全局變量的引用,所以它修改了外部值。

但是請注意,該對象的引用,因此,如果你寫這樣的:

function funky(parameter){ 
    parameter.hello = null; 
} 

然後調用funky不直接修改對象的參數引用。

var x = { hello: [] }; 
funky(x); // x => { hello: null } 

這只是我必須記住?

是的,瞭解參數如何通過是非常重要的。

如果將全局作用域中的已定義變量作爲參數傳遞,它將只將其新的賦值保存在函數的作用域內?

參數只在函數的範圍內保存它們的值。全局變量是全局的,所以如果它們在函數內被修改,它們會將該值保留在函數之外。

此外,請注意隱藏 —如果參數與全局變量具有相同的名稱,則該參數將該變量隱藏在該函數的範圍內。

1

對此:

變種你好被作爲參數傳遞,而內部時髦,它具有值零,當外你好在全局空間被調用時,它保持一個空數組的值。

不要以爲parameter別名hello。它們是不同的變量。他們可以自由地指出不同的事情。在這種情況下分配一個值 - null - 至parameterhello沒有影響。在該行之後,全局變量hello仍然指向一個空數組。只有parameter指向空。

此外,funky(hello)傳遞的hellofunky功能。考慮以下幾點:

var arr = []; 

function addElements(arr) { 
    arr.push(5); 
    arr.push(77); 
} 

全球arr之後仍然是addElements執行空。函數內的arr與全局範圍內的arr不同。 (我要指出,每個arr的內容可能指向同一個對象,但是這是一個單獨的問題。)

(還要注意some languages do allow the sort of aliasing you seem to expect,但是這並不參數是如何在JavaScript中過去了。)

1

的JavaScript假定如果你給一個變量賦值,它就在全局範圍內 - 除非該變量聲明爲var。例如像這樣:

var bob = 22; //global scope 
function funky(parameter){ 
    parameter = null; //sets the var passed in to null 
    var bob = 44; //sets the bob 
} 
var hello = []; 
funky(hello); // hello still has the value of an empty array even after the function is invoked. 
bob; // value is 22 

由於函數的變量bobvar宣稱,它是由函數的局部範圍內擁有和對功能的範圍之外聲明的bob沒有影響。

關於物體在傳入函數時如何與基元不同,請查看Jonathan Snook的文章http://snook.ca/archives/javascript/javascript_pass以及@ p.s.w.g的有用評論。

+0

偉大的文章鏈接和解釋,謝謝@哈維 – HelloWorld

+1

謝謝@Codey。你在問正確的問題。我認爲別人推薦道格拉斯克羅克福德的書,JavaScript:好部分,我同意。如果你還沒有購買紙質版本。 –

1

好的,下面的例子會讓你更加困惑。

var a = {'a':'A'};

函數foo(PARAM){param.a = 'B';}

FOO的(a);

//現在打印 {「一」:「B」}

這裏有一個重要的概念:

原語是按值傳遞,對象由「參考副本」通過。

至於更多的信息,您可以檢查這個答案: Does Javascript pass by reference?

+0

哈哈,這讓我更困惑,但這是我沒有很好的理解。感謝您指出@yang – HelloWorld