ここで何が起こっているかをよりよく示すために、例を変更しました。Demo
まず、3つのプロパティを持つオブジェクトを作成します。数値、文字列、および文字列値を持つ1つのプロパティを持つオブジェクト。
次に、Object.create()
;を使用して最初のオブジェクトから2番目のオブジェクトを作成します。
var obj1 = {
num : 1,
str : 'foo',
obj : { less: 'more' }
};
var obj2 = Object.create( obj1 );
console.log( '[1] obj1:', obj1 );
console.log( '[1] obj2:', obj2 );
"[1] obj1:"
[object Object] {
num: 1,
obj: [object Object] {
less: "more"
},
str: "foo"
}
"[1] obj2:"
[object Object] {
num: 1,
obj: [object Object] {
less: "more"
},
str: "foo"
}
よさそうですか?最初のオブジェクトと2番目のコピーされたオブジェクトがあります。
そんなに早くない; 最初のオブジェクトの値のいくつかを変更するとどうなるか見てみましょう。
obj1.num = 3;
obj1.str = 'bar';
obj1.obj.less = 'less';
console.log( '[2] obj1:', obj1 );
console.log( '[2] obj2:', obj2 );
"[2] obj1:"
[object Object] {
num: 3,
obj: [object Object] {
less: "less"
},
str: "bar"
}
"[2] obj2:"
[object Object] {
num: 3,
obj: [object Object] {
less: "less"
},
str: "bar"
}
ここでも、変更を加えた最初のオブジェクトと、そのオブジェクトのコピーがあります。ここで何が起こっているのですか?
オブジェクトに独自のプロパティがあるかどうかを確認しましょう。
for( var prop in obj1 ) console.log( '[3] obj1.hasOwnProperty( ' + prop + ' ): ' + obj1.hasOwnProperty( prop ) );
for( var prop in obj2 ) console.log( '[3] obj2.hasOwnProperty( ' + prop + ' ): ' + obj2.hasOwnProperty( prop ) );
"[3] obj1.hasOwnProperty( num ): true"
"[3] obj1.hasOwnProperty( str ): true"
"[3] obj1.hasOwnProperty( obj ): true"
"[3] obj2.hasOwnProperty( num ): false"
"[3] obj2.hasOwnProperty( str ): false"
"[3] obj2.hasOwnProperty( obj ): false"
obj1
定義したように、すべての独自のプロパティがありますが、そうでobj2
はありません。
obj2
のプロパティの一部を変更するとどうなりますか?
obj2.num = 1;
obj2.str = 'baz';
obj2.obj.less = 'more';
console.log( '[4] obj1:', obj1 );
console.log( '[4] obj2:', obj2 );
for( var prop in obj1 ) console.log( '[4] obj1.hasOwnProperty( ' + prop + ' ): ' + obj1.hasOwnProperty( prop ) );
for( var prop in obj2 ) console.log( '[4] obj2.hasOwnProperty( ' + prop + ' ): ' + obj2.hasOwnProperty( prop ) );
"[4] obj1:"
[object Object] {
num: 3,
obj: [object Object] {
less: "more"
},
str: "bar"
}
"[4] obj2:"
[object Object] {
num: 1,
obj: [object Object] {
less: "more"
},
str: "baz"
}
"[4] obj1.hasOwnProperty( num ): true"
"[4] obj1.hasOwnProperty( str ): true"
"[4] obj1.hasOwnProperty( obj ): true"
"[4] obj2.hasOwnProperty( num ): true"
"[4] obj2.hasOwnProperty( str ): true"
"[4] obj2.hasOwnProperty( obj ): false"
だから、私たちが望んでいたようにではなく、オンにnum
変更str
しましたが、必要のないときに変更しました。obj2
obj1
obj1.obj.less
チェックから、hasOwnProperty()
変更したにもかかわらず、最初obj2.obj.less
に設定しなかったことがわかります。obj2.obj
これは、まだ参照していることを意味しobj1.obj.less
ます。
からオブジェクトを作成しobj1.obj
て割り当て、それobj2.obj
が私たちが探しているものを提供するかどうかを確認しましょう。
obj2.obj = Object.create( obj1.obj );
console.log( '[5] obj1:', obj1 );
console.log( '[5] obj2:', obj2 );
for( var prop in obj1 ) console.log( '[5] obj1.hasOwnProperty( ' + prop + ' ): ' + obj1.hasOwnProperty( prop ) );
for( var prop in obj2 ) console.log( '[5] obj2.hasOwnProperty( ' + prop + ' ): ' + obj2.hasOwnProperty( prop ) );
"[5] obj1:"
[object Object] {
num: 3,
obj: [object Object] {
less: "more"
},
str: "bar"
}
"[5] obj2:"
[object Object] {
num: 1,
obj: [object Object] {
less: "more"
},
str: "baz"
}
"[5] obj1.hasOwnProperty( num ): true"
"[5] obj1.hasOwnProperty( str ): true"
"[5] obj1.hasOwnProperty( obj ): true"
"[5] obj2.hasOwnProperty( num ): true"
"[5] obj2.hasOwnProperty( str ): true"
"[5] obj2.hasOwnProperty( obj ): true"
それは良いことですが、今でobj2
は独自のobj
特性があります。今変わるとどうなるか見てみましょうobj2.obj.less
。
obj2.obj.less = 'less';
console.log( '[6] obj1:', obj1 );
console.log( '[6] obj2:', obj2 );
"[6] obj1:"
[object Object] {
num: 3,
obj: [object Object] {
less: "more"
},
str: "bar"
}
"[6] obj2:"
[object Object] {
num: 1,
obj: [object Object] {
less: "less"
},
str: "baz"
}
つまり、作成されたオブジェクトのプロパティがまだ変更されていない場合、そのプロパティの作成されたget
オブジェクトへのリクエストはすべて元のオブジェクトに転送されます。
前のコードブロックからのリクエストset
には、最初にのリクエストが必要ですが、その時点では存在しないため、に転送され、次にに転送されます。obj2.obj.less = 'more'
get
obj2.obj
obj2
obj1.obj
obj1.obj.less
obj2
最後にもう一度読んだとき、リクエストが転送されて以前に変更した設定が返されるobj2.obj
ように設定されていないため、2番目のオブジェクトオブジェクトの子のプロパティを変更すると両方が変更されるように見えますが、実際には実際には最初の変更のみです。get
obj1.obj
この関数を使用して、元のオブジェクトから完全に分離された新しいオブジェクトを再帰的に返すことができます。
Demo
var obj1 = {
num : 1,
str : 'foo',
obj : { less: 'more' }
};
var obj2 = separateObject( obj1 );
function separateObject( obj1 ) {
var obj2 = Object.create( Object.getPrototypeOf( obj1 ) );
for(var prop in obj1) {
if( typeof obj1[prop] === "object" )
obj2[prop] = separateObject( obj1[prop] );
else
obj2[prop] = obj1[prop];
}
return obj2;
}
console.log( '[1] obj1:', obj1 );
console.log( '[1] obj2:', obj2 );
for( var prop in obj1 ) console.log( '[1] obj1.hasOwnProperty( ' + prop + ' ): ' + obj1.hasOwnProperty( prop ) );
for( var prop in obj2 ) console.log( '[1] obj2.hasOwnProperty( ' + prop + ' ): ' + obj2.hasOwnProperty( prop ) );
"[1] obj1:"
[object Object] {
num: 1,
obj: [object Object] {
less: "more"
},
str: "foo"
}
"[1] obj2:"
[object Object] {
num: 1,
obj: [object Object] {
less: "more"
},
str: "foo"
}
"[1] obj1.hasOwnProperty( num ): true"
"[1] obj1.hasOwnProperty( str ): true"
"[1] obj1.hasOwnProperty( obj ): true"
"[1] obj2.hasOwnProperty( num ): true"
"[1] obj2.hasOwnProperty( str ): true"
"[1] obj2.hasOwnProperty( obj ): true"
ここでいくつかの変数を変更するとどうなるか見てみましょう。
obj1.num = 3;
obj1.str = 'bar';
obj1.obj.less = 'less';
console.log( '[2] obj1:', obj1 );
console.log( '[2] obj2:', obj2 );
"[2] obj1:"
[object Object] {
num: 3,
obj: [object Object] {
less: "less"
},
str: "bar"
}
"[2] obj2:"
[object Object] {
num: 1,
obj: [object Object] {
less: "more"
},
str: "foo"
}
すべてが期待どおりに機能します。