3

異なるインスタンスが個別に変更できるように、プロパティを値でコピーしようとしています。私の理解では、jQueryまたはZeptoの$ .extendを使用することは、「値によるコピー」を行うための優れた方法です。私の状況では機能していません。その理由を理解したいと思います。何が間違っているのかわかりません。

var c = [ {'purple' : 1}, { 'red':2 } ]
var x = { 'name': 'my obj', 'colors': c }
var doWork = function(passX) {
  var inY = $.extend({},passX);
  inY.colors[0].selected = true;
  return inY;
}
var y = doWork(x);

console.log( x.colors[0].selected );// true, but I think it should be undefined
console.log( y.colors[0].selected );​// true

本当に中心的なものが欠けているような気がします。同じオブジェクトから拡張してコピーを実行することはできませんか?関数の引数のスコープについて何か混乱がありますか?

jsFiddle: http: //jsfiddle.net/zfnyp/5/

編集:@Nikoが指摘しているように、私の混乱に対する答えは、ディープコピーがすべての子プロパティの値によるコピーバージョンを作成することです。深いコピーと浅いコピーは、コピーがいくつのプロパティを深くするかを意味すると思いました。おっと。

もう一度編集:Javascriptではディープコピーは面倒です。JQueryにはそれがありますが、ZeptoとUnderscoreにはありません。うまく実装するのは不可能だと言う人もいます。私の問題にこれを実装するために、オブジェクトの構造を知ることに依存するこのソリューションを作成しました。不格好ですが、これが私にとって正しい答えだと思います。

var c = [ {'purple' : 1, 'selected':false }, { 'red':2 } ]
var x = { 'name': 'my obj', 'colors': c }
var doWork = function(passX) {
  var inY = $.extend({},passX);
  inY.colors = $.extend([], passX.colors);
  for (var i = 0; i < passX.colors.length; i++) {
    inY.colors[i] = $.extend({}, passX.colors[i]);
  }
  inY.colors[0].selected = true;
  return inY;
}
var y = doWork(x);

console.log( x.colors[0].selected );
console.log( y.colors[0].selected );
4

5 に答える 5

4

x = yxとyが同じオブジェクトを参照するようにするため、y.colors上書きも行います。この場合、これはまったく役に立ちません。x.colors$.extend()

var x = { 'name': 'my obj', 'colors': c };
var y = $.extend(true, {}, x); // <-- first param "true" = make deep copy,
                               //     because otherwise "x.colors === y.colors"

配列もオブジェクトであるため、浅いコピーを実行するときに参照によってコピーされるため、深いコピーが必要です。

または新しいコードで:

var inY = $.extend(true, {}, passX); // deep copy = also copy mod.colors by value
于 2012-06-27T17:04:24.457 に答える
1

いいえ、それは変数xyが同じオブジェクトを指しているためです。新しい値に設定y.colorsすると、にアクセスするときにその値を取得できますx.colors。これ$.extend([],x.colors)は、オリジナルのコピーはcここでは重要ではありません。

xしかし、とyが異なるcolors配列を持つ異なるオブジェクトである場合でも、機能しません。使用する

var purple = {purple: 1}, red = {red: 2};
var colors = [purple, red];
var copy = $.extend([], colors);

それでも同じようにcopy[0]指し示します。オプションを使用することをお勧めします:purplecolors[0]deep

var x = {name:'my obj', colors:[{purple: 1}, {red:2}]};
var y = $.extend(true, {}, x);
于 2012-06-27T17:07:54.067 に答える
1

あなたはこのようなものが欲しいです:

var c = [ {'purple' : 1}, { 'red':2 } ]
var x = { 'name': 'my obj', 'colors': c };
var y = { 'name': 'my obj', 'colors': c };

y.colors = $.extend([],x.colors);

x.colors[0].selected = true;

console.log( x.colors[0].selected ); // true
console.log( y.colors[0].selected ); // now it's an error because y.colors[0] is undefined

デモ

于 2012-06-27T17:04:49.403 に答える
1

これを引き起こしているのはコピーではなく、var x = y = {です。yオブジェクトに設定してから、に設定xしますy。そのためxy同じオブジェクトを指します。

オブジェクトを変数の1つに設定してから、もう1つにコピーする必要があります。

var x = { 'name': 'my obj', 'colors': c };
var y = $.extend({}, x);
于 2012-06-27T17:04:54.917 に答える
0

このメソッド$.extendは、ディープコピーを実行できます。あなたがしなければならないのは、最初の位置に新しいパラメータを追加することです-それはディープコピーモードtrueにフラグを立てます-そして残りのパラメータを右にシフトします。

var o1 = {"a": "AA", "n": 11, "o": {"k0": "v0", "k1": "v1"}};
var oz = $.extend(true, {}, o1)
oz.o.k0 = 99;

dump(o1); // {a:"AA", n:99, o:{k0:"v0", k1:"v1"}}
dump(oz); // {a:"AA", n:99, o:{k0:99, k1:"v1"}}
于 2012-06-27T17:23:37.973 に答える