2012-11-10 78 views
1

我已經盡力解決了這個問題,現在我被卡住了,爲什麼第四次提醒返回undefined?在JavaScript中設置對象值

function buttonClick() 
{ 
    var myTest = function() 
    { 
    var _setDirectlyInside = "So far so good..."; 
    var _setInFunctionCalledInside; 
    var _setInFunctionCalledFromOutside; 

    (function(){ 
     _setInFunctionCalledInside = "This would indicate scope isn't the problem?"; 
    })(); 

    return { 
     basic : "Easy stuff", 
     setDirectlyInside : _setDirectlyInside, 
     setInFunctionCalledInside : _setInFunctionCalledInside, 
     functionCallFromOutside : function(){ 
     _setInFunctionCalledFromOutside = "Why does this come back as undefined?"; 
     }, 
     setInFunctionCalledFromOutside : _setInFunctionCalledFromOutside 
    } 
    }; 

    var test = myTest(); 

    alert(test.basic); // Returns "Easy stuff" 
    alert(test.setDirectlyInside); // Returns "So far so good..." 
    alert(test.setInFunctionCalledInside); // Returns "This would indicate scope isn't the problem?" 

    test.functionCallFromOutside(); 
    alert(test.setInFunctionCalledFromOutside); // Broken, returns undefined 
} 

分辨率:

setInFunctionCalledFromOutside : _setInFunctionCalledFromOutside, // Won't work 
setInFunctionCalledFromOutsideGetter : function(){ 
    return _setInFunctionCalledFromOutside; // Will work 
} 

... 

alert(test.setInFunctionCalledFromOutside); // Broken, returns undefined 
alert(test.setInFunctionCalledFromOutsideGetter()); // Now works 

回答

2

此:

return { 
    basic : "Easy stuff", 
    setDirectlyInside : _setDirectlyInside, 
    setInFunctionCalledInside : _setInFunctionCalledInside, 
    functionCallFromOutside : function(){ 
    _setInFunctionCalledFromOutside = "Why does this come back as undefined?"; 
    }, 
    setInFunctionCalledFromOutside : _setInFunctionCalledFromOutside 
} 

...不會造成setInFunctionCalledFromOutside總是返回_setInFunctionCalledFromOutside相同的值。相反,_setInFunctionCalledFromOutside將在return語句執行時進行評估,並且其值將被放置在setInFunctionCalledFromOutside中。因此,functionCallFromOutside()將不會對setInFunctionCalledFromOutside產生影響。

+0

我以爲functionCallFromOutside只包含函數定義,它會稍後執行「test.functionCallFromOutside()」?我的思想在哪裏錯了? – Lee

+1

這不是你思考錯誤的地方。它*在你調用'test.functionCallFromOutside()'時執行。問題是你期望當函數設置_setInFunctionCalledFromOutside =「爲什麼這會回到未定義的狀態?」它還會*更新'setInFunctionCalledFromOutside'屬性。 – Jacob

+0

啊,我看到我錯了什麼地方,我沒想到它也會更新值,但我感覺setInFunctionCalledFromOutside更像是一個C#getter屬性...將其更改爲一個函數,然後我稱它爲一個吸氣劑給出了預期的結果。謝謝你的幫助! – Lee

1

@nnnnnnsaid it best,但他刪除了他的答案。 setInFunctionCalledFromOutside不是指針_setInFunctionCalledFromOutside。在返回的對象創建時,setInFunctionCalledFromOutside被分配了_setInFunctionCalledFromOutside所具有的值。由於尚未分配任何值,因此該值爲undefined。改變一個的值,不會改變另一個的值。

示出相同的原理一個更簡單的例子:

var i = 0; 
var n = i; 
i++; 
alert(i); // 1 
alert(n); // still 0 
1

要添加到其他 - 供參考,JS按值傳遞字符串和數字。 它通過引用傳遞/分配對象,數組和函數。

這不是想象中的那麼你打的(因爲內部變量是由undefined你把它分配給你的外部變量的時間)的障礙,但即使你沒有得到的第一部分固定:

var internal = "string"; 
return { 
    external : internal, 
    setInternal : function (val) { internal = val; } 
}; 

這仍然不能解決問題,因爲obj.external將始終是「字符串」。
爲什麼?
因爲您在分配時將external設置爲與internal相同的值,並且不等於internal(即:指向它的指針)的reference

如果你正在尋找一個指針,然後做internal對象:

var internal = { string : "my string" }; 
return { 
    external : internal, 
    setInternal : function (val) { internal.string = val; } 
}; 

obj.external.string; // "my string" 
obj.setInternal("Bob was here"); 
obj.external.string; // "bob was here" 

爲什麼它現在的工作?
由於內部是一個對象,並且當您分配external的值時,您會爲其指定一個指向internal也有指針的對象。
當您更改internal的屬性時,如internal.string,因爲external指向同一對象,因此external.string具有相同的值。

如果設置internal到完全不同的東西,那麼你在別的指着internal(如internal = null;),因此external將不再改變,當你修改internal,因爲internal不再是在對象指向它以前是。