2012-05-11 70 views
2

我是Javascript新手(一般編程),並且一直在尋找一種方法來改變任意數量的參考值Javascript功能。 (JavaScript variable number of arguments to function)很有幫助。我能夠使用它來創建我需要的兩個功能,但是我在第三個功能上遇到了問題。使用可變數量參數的Javascript函數 - 更改它們的值 - 然後返回它們

基本上我想通過可變數量的對象(原始或更復雜的)到一個函數,並具有函數更改每個對象的值。

var pants = true; 
var house = true; 
var hair = {/* lots of stuff */}; 

var onFire = function() { 
     for (var i = 0; i < arguments.length; i++) { 
      arguments[i] = false; 
     } 
}; 

onFire(pants, house, hair); 

控制檯輸出:

>pants; 
true 

>house; 
true 

>hair; 
Object 

我怎樣才能制定這一功能,因此其結果是:

>pants; 
false 

>house; 
false 

>hair; 
false 

任何幫助將不勝感激!

編輯:

爲了澄清的事情 - 我想創建一個可重複使用的輔助函數傳入的任何對象的值更改爲false而不是鍵入:

var a1 = false; 
var a2 = false; 
... 
var a+n = false; 

如果我使用mathec的方法 - 是否有可能'解析'object,以便它的屬性覆蓋同名的全局變量,還是我堅持每次明確地輸入它?

var object = { 
    pants: {/* lots of stuff */}, 
    house: {/* lots of stuff */}, 
    hair: {/* lots of stuff */} 
}; 

function modifyObject(obj) { 
    obj.pants = false; 
    obj.house = false; 
    obj.hair = false; 
} 

function someMagic(object){ 
    // wand waves... 
    // rabbit exits hat.... 
} 

控制檯輸出:

>pants; 
false 

>house; 
false 

>hair; 
false 

回答

5

當您通過在JavaScript中要傳遞一個參考的副本到一個值,如果它是一個對象變量,但是如果它是一個原始的(如真/假)你複製的實際值。這基本上意味着,如果您傳遞一個對象並修改其中一個對象的屬性,那麼您將修改原始對象。但是如果你傳入一個像true/false的原語,你只需要修改副本,而不是原始值。因此,如果您的目標是修改原始值,則可以選擇將這些值存儲在對象中,然後傳遞該對象。例如:

var object = { 
    pants: true, 
    house: true, 
    hair: {} 
}; 

function modifyObject(obj) { 
    obj.pants = true; 
    obj.house = true; 
    obj.hair = true; 
} 

如果您想修改任意數量的參數,請記住,如果您傳遞的是true/false,那麼您正在複製這些值。所以如果你在函數內改變它們,你將不會修改原始值。

一個快速的方法來記住這是如果你曾經傳過一個對象或數組,你正在修改實際的對象。別的,你正在修改一個副本。

編輯

所以解釋你想從字面上做什麼,你可以這樣寫:

var a = true, 
    b = true; 

/* pass in variable names */ 
function makeFalse() { 
    var i, len; 

    for (i = 0, len = arguments.length; i < len; ++i) { 
    window[arguments[i]] = false; 
    } 
} 

makeFalse("a", "b"); 

但我不能想到一個很好的理由這樣做:-)。我會使用配置對象來存儲標誌和狀態變量,而不是全局變量。

+1

很好的解釋,除了修改對象變量本身不會做任何事情,但修改它的屬性將有一個例外。 –

+0

感謝您的澄清!我發現一個很好的方式來思考,變量標籤或名稱與它們指向的值是分開的。變量名稱在函數中總是分開的。如果您在函數內重新分配變量,則只需重新分配該局部變量。 – cmather

+0

這是一個很好的解釋。只是讓我畏縮思考指針.... –

1

不幸的是,這是不能直接成爲可能。

JavaScript是一種通按值的語言,並且在對象類型的情況下,它的一個傳值作爲參考(至少這就是伊夫如何看到它稱爲)

Is JavaScript a pass-by-reference or pass-by-value language?

去相當深入,https://stackoverflow.com/a/3638034/1093982尤其有一個很好的答案。

這裏是一個展示的jsfiddle在上面的回答的例子:

http://jsfiddle.net/hjPHJ/

注意到任何分配給一個參數是如何帶入上述範圍。

0

你可以嘗試JavaScript的typeof()函數,它應該返回「object」,然後在代碼中以不同的方式對待它。至於改變一個對象的價值,我認爲你實際上想改變一個屬性的價值,但我不確定我是否足夠了解你的問題。

要更改對象屬性,您可以這樣做。

hair.color = 'red'; 

如果你想取消設置對象,你可以這樣做。

delete window.some_var; 
+0

我正在專注於對象。正如mathec指出的那樣,你不能以這種方式改變原始變量,但你可以將它們作爲單個對象來傳遞。 –

0

JavaScript通過每個參數作爲參數的值,所以當您更改傳入的參考值時,它會修改複製的值。

然而它確實有其他的東西是非常強大的,這就是封閉。在您的示例中,onFire已通過閉包範圍訪問pants,househair,並且可以直接修改它們。

0

當你在javascript中調用函數時,你傳遞的是值而不是對原始對象的引用。有幾種方法可以做你想做的事情,但不是直接通過傳遞每個值來改變功能。

首先可以傳遞的數組:

function onFire(arr) { 
    for (var i = 0; i < arr.length; i++) { 
     arr[i] = false; 
    } 
} 

arr = [true, true, {}]; 
onFire(arr); // arr[0] through arr[2] are now false 

另一個辦法是通過一個對象,其屬性可以進行修改,你就不能改變變量的傳遞作爲參數的值:

function onFire(obj) { 
    obj.pants = false; 
    obj.house = false; 
    obj.hair = false; 
} 

onFire({ pants: true, house: true, hair: { } }); 
// obj.pants, obj.house and obj.hair are now false 

這些都不只是完成你想要的東西,但如果我知道這樣做的原因你問有可能是一個更好的辦法...

相關問題