26

グローバルスコープで、関数の外で定義されたオブジェクトがあります。このオブジェクトは引数として関数に渡されませんが、関数はそれを変更し、変更されたオブジェクトを返します。

私が知りたかったのは、関数がオブジェクトのコピーを返すか、元のグローバル オブジェクトを返すかということです。

また、オブジェクトは参照によって関数に渡されるため、そのオブジェクトを引数として関数に渡すと違いがありますか?

4

5 に答える 5

57

オブジェクトを返すときはいつでも、オブジェクトへの参照を返しています。同様に、オブジェクトを渡すときは参照を渡します。ただし、これらの例が示すように、オブジェクトを引数として渡すことは、グローバル スコープでオブジェクトを変更することとは異なる場合があります。これは、オブジェクトへの参照自体が値によって渡されるためです。

オブジェクトのメンバーを変更する場合、それを引数として渡すか、単にグローバル オブジェクトを更新するかは違いはありません。いずれにせよ、同じオブジェクトで作業しています。

例 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'}
于 2013-02-21T16:03:33.360 に答える
3

遅いコメントかもしれませんが、これはどの言語でも典型的な課題です。プリミティブ (値渡し) とは対照的に、ヒープ上に作成され、参照によって渡されるオブジェクト。問題の根本は、好ましくない影響を避けるための共有インスタンスと一意のインスタンスであると思います。たとえば、関数を呼び出して、新しいユーザーがコレクションに追加するテンプレート (オブジェクト) を取得したり、別のモジュールからキャンセル イベントでフォームをクリアして最初からやり直したりします。理解しやすく、見落としやすい..通常、テストケースはすべての使用順列をカバーしていません

健全性チェックリスト:

共有インスタンスは次のとおりです。

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
于 2017-10-07T16:09:43.330 に答える
1

私が知りたかったのは、関数がオブジェクトのコピーを返すか、元のグローバル オブジェクトを返すかということです。

事実上、JavaScript でオブジェクトへの参照のみを処理します。var foo = {}新しいオブジェクトへの参照を に割り当てるだけですfoo

于 2013-02-21T15:43:20.573 に答える
1

オブジェクトが関数の外にある場合、それを「返す」必要はありません。関数内でオブジェクトを変更すると、オブジェクト自体が更新されます。その後、必要に応じて、新しく更新されたオブジェクトを他の関数で参照できます。

于 2013-02-21T15:44:16.093 に答える
1

あなたの質問から、これはあなたのコードがどのように見えるかです(多かれ少なかれ):

var o = {};

function f() {
    o.prop = true;
    return o;
}
  1. この場合、グローバル変数oはオブジェクトを参照します。
  2. 変更すると、参照oが何であれ変更されます。oしたがって、元のオブジェクトを変更します。
  3. 戻ると、元のオブジェクトへの参照が返さoれます。

オブジェクトを関数に渡すと、元のオブジェクトへの参照が渡されます。したがって、変更は元のオブジェクトに影響します。例えば:

var o = {};

f(o);

console.log(o.prop); // true

function f(o) {
    o.prop = true;
}
于 2013-02-21T15:56:54.617 に答える