グローバルスコープで、関数の外で定義されたオブジェクトがあります。このオブジェクトは引数として関数に渡されませんが、関数はそれを変更し、変更されたオブジェクトを返します。
私が知りたかったのは、関数がオブジェクトのコピーを返すか、元のグローバル オブジェクトを返すかということです。
また、オブジェクトは参照によって関数に渡されるため、そのオブジェクトを引数として関数に渡すと違いがありますか?
グローバルスコープで、関数の外で定義されたオブジェクトがあります。このオブジェクトは引数として関数に渡されませんが、関数はそれを変更し、変更されたオブジェクトを返します。
私が知りたかったのは、関数がオブジェクトのコピーを返すか、元のグローバル オブジェクトを返すかということです。
また、オブジェクトは参照によって関数に渡されるため、そのオブジェクトを引数として関数に渡すと違いがありますか?
オブジェクトを返すときはいつでも、オブジェクトへの参照を返しています。同様に、オブジェクトを渡すときは参照を渡します。ただし、これらの例が示すように、オブジェクトを引数として渡すことは、グローバル スコープでオブジェクトを変更することとは異なる場合があります。これは、オブジェクトへの参照自体が値によって渡されるためです。
オブジェクトのメンバーを変更する場合、それを引数として渡すか、単にグローバル オブジェクトを更新するかは違いはありません。いずれにせよ、同じオブジェクトで作業しています。
例 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'}
遅いコメントかもしれませんが、これはどの言語でも典型的な課題です。プリミティブ (値渡し) とは対照的に、ヒープ上に作成され、参照によって渡されるオブジェクト。問題の根本は、好ましくない影響を避けるための共有インスタンスと一意のインスタンスであると思います。たとえば、関数を呼び出して、新しいユーザーがコレクションに追加するテンプレート (オブジェクト) を取得したり、別のモジュールからキャンセル イベントでフォームをクリアして最初からやり直したりします。理解しやすく、見落としやすい..通常、テストケースはすべての使用順列をカバーしていません
健全性チェックリスト:
共有インスタンスは次のとおりです。
var bigo = {
usr: { name: 'steven' },
bigi: function () {
return this.usr;
}
};
var outA = bigo.bigi();
var outB = bigo.bigi();
print(outA.name); // => steven
print(outB.name); // => steven
outA.name = 'ilan'; // change value
print(outA.name); // => ilan
print(outB.name); // => ilan
非共有インスタンス:
var bigo = {
bigi: function () {
var user = { name: 'steven' };
return user;
}
};
var outA = bigo.bigi();
var outB = bigo.bigi();
print(outA.name); // => steven
print(outB.name); // => steven
outA.name = 'ilan'; // change value
print(outA.name); // => ilan
print(outB.name); // => steven
私が知りたかったのは、関数がオブジェクトのコピーを返すか、元のグローバル オブジェクトを返すかということです。
事実上、JavaScript でオブジェクトへの参照のみを処理します。var foo = {}
新しいオブジェクトへの参照を に割り当てるだけですfoo
。
オブジェクトが関数の外にある場合、それを「返す」必要はありません。関数内でオブジェクトを変更すると、オブジェクト自体が更新されます。その後、必要に応じて、新しく更新されたオブジェクトを他の関数で参照できます。
あなたの質問から、これはあなたのコードがどのように見えるかです(多かれ少なかれ):
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;
}