一尘不染

JavaScript:如何按值传递对象?

javascript

  • 当将对象作为参数传递时,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


  1. 除了创建本地副本/克隆以外,还有没有更好的方法可以按值传递对象?

阅读 808

收藏
2020-05-01

共1个答案

一尘不染

并不是的。

根据你的实际需要,一个 可能性 可能是集o作为一个新的对象的原型。

var o = {};
(function(x){
    var obj = Object.create( x );
    obj.foo = 'foo';
    obj.bar = 'bar';
})(o);

alert( o.foo ); // undefined

因此,您添加到的任何属性obj都不会添加到中oobj使用与中的属性相同的属性名称添加到的任何属性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'

在这里您可以看到,因为您没有使用bazon obaz属性将on 遮蔽在Array 上obj,所以o.bazArray被修改了。

因此,您需要先对其进行阴影处理:

var o = {
    baz: []
};
(function(x){
    var obj = Object.create( x );

    obj.baz = [];
    obj.baz.push( 'new value' );

})(o);

alert( o.baz[0] );  // undefined
2020-05-01