我有一個在全局範圍內的函數之外定義的對象。該對象不作爲參數傳遞給函數,但該函數會修改它並返回修改後的對象。JavaScript函數默認情況下是否通過引用或值返回對象?
我想知道的是,如果函數返回對象的副本或原始全局對象?
此外,將該對象作爲參數傳遞給函數,有所作爲,因爲通過引用將對象傳遞給函數?
我有一個在全局範圍內的函數之外定義的對象。該對象不作爲參數傳遞給函數,但該函數會修改它並返回修改後的對象。JavaScript函數默認情況下是否通過引用或值返回對象?
我想知道的是,如果函數返回對象的副本或原始全局對象?
此外,將該對象作爲參數傳遞給函數,有所作爲,因爲通過引用將對象傳遞給函數?
每當你返回一個對象,你返回對象的引用。同樣,當你傳遞一個對象時,你傳遞了一個引用。但是,將參數作爲參數傳遞給可能與僅改變全局範圍內的對象不同,如這些示例所示。這是因爲對象的引用本身是按值傳遞的。
如果您要更改對象的成員,那麼無論您是將其作爲參數傳遞還是更新全局對象都沒有區別。無論哪種方式,你正在使用同一個對象。
例1:
var object = {foo:'original'};
function changeObject() {
object.foo = 'changed';
return object;
}
console.log(changeObject()); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'changed'}
例2:
var object = {foo:'original'};
function changeArgument(object) {
object.foo = 'changed';
return object;
}
console.log(changeArgument(object)); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'changed'}
在另一方面,如果你覆蓋了新對象的對象,該變化不會,如果你堅持這樣做它的參數,但如果你對全局對象做這件事,它將會持續下去。這是因爲參數按值傳遞了對象的引用。一旦你用一個新對象的引用替換這個值,你就不再談論同一個對象了。
例3:
var object = {foo:'original'};
function replaceObject() {
object = {foo:'changed'};
return object;
}
console.log(replaceObject()); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'changed'}
例4:
var object = {foo:'original'};
function replaceArgument(object) {
object = {foo:'changed'};
return object;
}
console.log(replaceArgument(object)); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'original'}
當然,如果你希望'replaceArgument(object)'和'replaceObject'具有相同的最終結果,你可以'object = replaceArgument(object)' – 2013-02-21 16:06:05
這是一個很好的答案。 – rgthree 2013-02-21 17:09:45
我想知道的是,如果函數返回對象的副本或原始全局對象?
實際上,您只處理JavaScript中對象的引用。即使var foo = {}
只是將對新的對象的引用分配給foo
。
如果對象在函數之外,則不需要「返回」它。如果修改函數內的對象,它將更新對象本身。然後,您可以根據需要在其他函數中引用新更新的對象。
這是有道理的。但是,就我而言,返回它有助於將單個對象從巨大的集合中分離出來,這樣我就不需要再次查找該對象。 – 2013-02-21 15:52:18
嗯。不知道我理解你的情況。你能發佈一個代碼示例嗎? – LoneWolfPR 2013-02-21 16:00:52
從你的問題,這是我怎麼想你的代碼看起來(或多或少):
var o = {};
function f() {
o.prop = true;
return o;
}
o
引用的對象。o
時,您將修改任何o
引用。因此它修改了原始對象。o
時,您將返回對原始對象的引用。將對象傳遞給函數會導致對傳遞的原始對象的引用。因此任何修改都會影響原始對象。例如:
var o = {};
f(o);
console.log(o.prop); // true
function f(o) {
o.prop = true;
}
可能會遲到評論,但是這是在任何語言的典型挑戰。 Obects在堆上創建,並通過引用與基元(按值)相對傳遞。 我認爲問題的根源是共享實例與獨特實例,以避免不受歡迎的影響。 例如我們調用一個函數來獲取新用戶添加到集合的模板(對象),或者想要清除不同模塊的取消事件的表格 以重新開始。這很容易理解和容易overlook..test案件通常 沒有覆蓋所有使用排列
理智清單: 這裏共享實例:
var bigo = {
usr: {name: 'steven'},
bigi: function() {
return this.usr;
}
};
var outA = bigo.bigi();
var outB = bigo.bigi();
print(outA.name);
print(outB.name);
outA.name = 'ilan'; // change value
print(outA.name);
print(outB.name);
以上的農產品:
steven
steven
ilan
ilan
非共享:
var bigo = {
bigi: function() {
var user = {name: 'steven'};
return user;
}
};
var outA = bigo.bigi();
var outB = bigo.bigi();
print(outA.name);
print(outB.name);
outA.name = 'ilan'; // change value
print(outA.name);
print(outB.name);
o輸出:
steven
steven
ilan
steven
只有明確地這樣做,纔不會複製對象。 – 2013-02-21 15:43:33
而不是說「對象通過引用傳遞給函數」,更準確地說,對象的*引用*是按值傳遞的。看到這裏:http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language/5314911#5314911 – 2013-02-21 15:46:06