当传递对象作为参数时,JavaScript会通过引用传递它们,从而难以创建对象的本地副本。
var o = {}; (function(x){ var obj = x; obj.foo = 'foo'; obj.bar = 'bar'; })(o)o将有.foo和.bar 。
克隆可以解决这个问题。 简单的例子:
var o = {}; function Clone(x) { for(p in x) this[p] = (typeof(x[p]) == 'object')? new Clone(x[p]) : x[p]; } (function(x){ var obj = new Clone(x); obj.foo = 'foo'; obj.bar = 'bar'; })(o)o将不会有.foo或.bar 。
题
除了创建本地副本/克隆之外,是否有更好的方式通过值传递对象?When passing objects as parameters, JavaScript passes them by reference and makes it hard to create local copies of the objects.
var o = {}; (function(x){ var obj = x; obj.foo = 'foo'; obj.bar = 'bar'; })(o)o will have .foo and .bar.
It's possible to get around this by cloning; simple example:
var o = {}; function Clone(x) { for(p in x) this[p] = (typeof(x[p]) == 'object')? new Clone(x[p]) : x[p]; } (function(x){ var obj = new Clone(x); obj.foo = 'foo'; obj.bar = 'bar'; })(o)o will not have .foo or .bar.
Question
Is there a better way to pass objects by value, other than creating a local copy/clone?最满意答案
不是真的。
根据您实际需要,一种可能性是将o设置为新对象的原型。
var o = {}; (function(x){ var obj = Object.create( x ); obj.foo = 'foo'; obj.bar = 'bar'; })(o); alert( o.foo ); // undefined所以你添加到obj任何属性都不会被添加到o 。 添加到obj任何属性与o的属性具有相同的属性名将会影响o属性。
当然,任何添加到o属性都可以从obj获得,如果它们没有被遮蔽,并且在原型链中有o所有对象都将看到与o相同的更新。
此外,如果obj具有引用另一个对象的属性(如Array),则需要确保在向对象添加成员之前对该对象进行阴影,否则,这些成员将被添加到obj ,并且将在所有obj之间共享在原型链中有对象的对象。
var o = { baz: [] }; (function(x){ var obj = Object.create( x ); obj.baz.push( 'new value' ); })(o); alert( o.baz[0] ); // 'new_value'在这里,您可以看到,因为您没有在obj上的baz上的baz上o.baz Array,所以o.baz Array被修改。
所以,你需要先影响它:
var o = { baz: [] }; (function(x){ var obj = Object.create( x ); obj.baz = []; obj.baz.push( 'new value' ); })(o); alert( o.baz[0] ); // undefinedNot really.
Depending on what you actually need, one possibility may be to set o as the prototype of a new object.
var o = {}; (function(x){ var obj = Object.create( x ); obj.foo = 'foo'; obj.bar = 'bar'; })(o); alert( o.foo ); // undefinedSo any properties you add to obj will be not be added to o. Any properties added to obj with the same property name as a property in o will shadow the o property.
Of course, any properties added to o will be available from obj if they're not shadowed, and all objects that have o in the prototype chain will see the same updates to o.
Also, if obj has a property that references another object, like an Array, you'll need to be sure to shadow that object before adding members to the object, otherwise, those members will be added to obj, and will be shared among all objects that have obj in the prototype chain.
var o = { baz: [] }; (function(x){ var obj = Object.create( x ); obj.baz.push( 'new value' ); })(o); alert( o.baz[0] ); // 'new_value'Here you can see that because you didn't shadow the Array at baz on o with a baz property on obj, the o.baz Array gets modified.
So instead, you'd need to shadow it first:
var o = { baz: [] }; (function(x){ var obj = Object.create( x ); obj.baz = []; obj.baz.push( 'new value' ); })(o); alert( o.baz[0] ); // undefined更多推荐
发布评论