2015-08-27 36 views
1
function Hello(name) { 

    function changeName(newName) { 
     name = newName; 
    } 

    return { 
     changeName: changeName, 
     name: name 
    }; 
} 

var o=Hello("Martin"); 

o.name; // "Martin" 

o.changeName("Marc"); 

o.name; // "Martin" 

從上面的代碼很明顯,changeName不會更改name屬性。作爲對象返回傳遞的參數

1.爲什麼?

2.什麼是changeName實際上在變化?

+0

你能正確調用'changeName'嗎? – Mritunjay

+0

請參閱編輯請 – dylan1994

回答

1

當你調用該函數Hello"Martin",變量name的聲明爲功能Hello參數值分配的"Martin"值。

當您將屬性name設置爲值name傳遞給該函數的對象返回時,該字符串將被複制。現在o.name有其自己的字符串,它與Hello函數中的變量name的值分開。對name的任何更改都不會影響現在在對象屬性上設置的值。這可以演示如下:

var name = "Martin"; 
var o = { 
    name: name 
}; 
name = "Marc"; 
console.log(o.name); // Martin 
console.log(name); // Marc 

這幾乎解決了您的第一個問題,但第一個問題的完整答案需要您的第二個問題的答案。當您在Hello函數中聲明changeName時,它會創建一個繼承變量nameclosure,這意味着只要在其他地方使用name(其中一個示例在其他閉包中),就會反映變量name的任何更改。這是很難在你的代碼,看看自從name使用後Hello運行在changeName唯一的地方,但你可以在下面的例子看到我的意思:

function Hello(name) { 
    function changeName(newName) { 
    name = newName; 
    } 

    function seeName() { 
    return name; 
    } 

    return { 
    changeName: changeName, 
    seeName: seeName, 
    name: name 
    }; 
} 

var o = Hello("Martin"); 

console.log(o.name); // "Martin" 

o.changeName("Marc"); 

console.log(o.name); // "Martin" 

console.log(o.seeName()); // "Marc" 

這兩個因素讓這個你changeName方法沒有你要找的效果。

1

您必須指定要更改使用「本」,否則「名」將只是一個局部變量對象的屬性...

嘗試:

function changeName(newName) { 
     this.name = newName; 
    } 
+3

我不想「糾正」代碼,只是理解爲什麼它的行爲如此。 – dylan1994

+0

@ dylan1994,你必須指定你想使用「this」來更改該對象的屬性,否則「name」將只是一個局部變量... – DZanella

+0

請編輯更多信息。只有代碼和「試試這個」的答案是[灰心](http://meta.stackexchange.com/questions/196187/is-try-this-bad-practice),因爲它們不包含可搜索的內容,也不解釋爲什麼有人應該「嘗試這個」。我們在這裏努力成爲知識的資源。 –

1
function changeName(newName) { 
    name = newName; 
} 

正在改變局部變量name(參數),而不是返回對象的屬性。因爲字符串是不可變的,所以當你這樣做時:

var str = "str"; 
var str2 = str; 

str和str2是不同的對象。如果修改str,則str2不會受到影響。

你可以做到以下幾點:

function Hello(name) { 

    function changeName(newName) { 
     obj.name = newName; 
    } 

    var obj = { 
     changeName: changeName, 
     name: name 
    }; 

    return obj; 
} 
0

this關鍵字,而你從changeName()方法返回名稱。

function Hello(name) { 

    function changeName(newName) { 
     this.name = newName; 
    } 

    return { 
     changeName: changeName, 
     name: name 
    }; 
} 

var o=Hello("Martin"); 

console.log(o.name); // "Martin" 

o.changeName("Marc"); 

console.log(o.name); 
0

您要儘量使PASSING BY VALUE OR BY REFERENCE

當通過在像一個字符串或數字基本類型的變量,該值由值傳遞英寸這意味着在函數中對該變量的任何更改都與函數外部發生的任何變化完全分離。

相關問題