JavaScript:如何按值传递对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7574054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:47:14  来源:igfitidea点击:

JavaScript: How to pass object by value?

javascript

提问by vol7ron

  • 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)
    

    owill have .fooand .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)
    

    owill not have .fooor .bar.

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



Question

  1. Is there a better way to pass objects by value, other than creating a local copy/clone?
  1. 除了创建本地副本/克隆之外,有没有更好的方法来按值传递对象?

采纳答案by user113716

Not really.

并不真地。

Depending on what you actually need, one possibilitymay be to set oas the prototype of a new object.

根据您的实际需要,一种可能性可能是设置o为新对象的原型。

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

alert( o.foo ); // undefined

So any properties you add to objwill be not be added to o. Any properties added to objwith the same property name as a property in owill shadow the oproperty.

因此,您添加到的任何属性obj都不会添加到o. 任何添加到obj与属性名称相同的属性都o将隐藏该o属性。

Of course, any properties added to owill be available from objif they're not shadowed, and all objects that have oin the prototype chain will see the same updates to o.

当然,如果添加到 的任何属性没有被隐藏,那么它们o将可用obj,并且o原型链中的所有对象都将看到对o.

Also, if objhas 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 objin the prototype chain.

此外,如果obj有一个属性引用另一个对象,如数组,则需要确保在向对象添加成员之前隐藏该对象,否则,这些成员将被添加到obj,并将在所有对象之间共享有obj原型链。

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 bazon owith a bazproperty on obj, the o.bazArray gets modified.

在这里,你可以看到,因为你没在阴影阵列bazo有一个baz关于财产objo.baz数组被修改。

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

回答by svimre

Check out this answer https://stackoverflow.com/a/5344074/746491.

查看此答案https://stackoverflow.com/a/5344074/746491

In short, JSON.parse(JSON.stringify(obj))is a fast way to copy your objects, if your objects can be serialized to json.

简而言之,JSON.parse(JSON.stringify(obj))如果您的对象可以序列化为 json ,则是一种复制对象的快速方法。

回答by Paul Varghese

Here is clone function that will perform deep copy of the object:

这是将执行对象深度复制的克隆函数:

function clone(obj){
    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = new obj.constructor(); 
    for(var key in obj)
        temp[key] = clone(obj[key]);

    return temp;
}

Now you can you use like this:

现在你可以像这样使用:

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

回答by Brandon

Use Object.assign()

Object.assign()

Example:

例子:

var a = {some: object};
var b = new Object;
Object.assign(b, a);
// b now equals a, but not by association.

A cleaner example that does the same thing:

一个更简洁的例子,做同样的事情:

var a = {some: object};
var b = Object.assign({}, a);
// Once again, b now equals a.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

回答by Andy E

You're a little confused about how objects work in JavaScript. The object's reference isthe value of the variable. There is no unserialized value. When you create an object, its structure is stored in memory and the variable it was assigned to holds a reference to that structure.

您对 JavaScript 中的对象如何工作感到有些困惑。对象的引用变量的值。没有未序列化的值。创建对象时,其结构存储在内存中,分配给它的变量保存对该结构的引用。

Even if what you're asking was provided in some sort of easy, native language construct it would still technically be cloning.

即使您所要求的是以某种简单的母语结构提供的,从技术上讲,它仍然是克隆。

JavaScript is really just pass-by-value... it's just that the value passed might be a reference to something.

JavaScript 实际上只是按值传递……只是传递的值可能是对某物的引用。

回答by user5242529

Use this

用这个

x = Object.create(x1);

xand x1will be two different object,change in xwill not change x1

x并且x1将是两个不同的对象,变化x不会改变x1

回答by JaredPar

Javascript always passes by value. In this case it's passing a copy of the reference ointo the anonymous function. The code is using a copy of the reference but it's mutating the single object. There is no way to make javascript pass by anything other than value.

Javascript 总是按值传递。在这种情况下,它将引用的副本传递给o匿名函数。该代码正在使用引用的副本,但它正在改变单个对象。没有办法让 javascript 传递值以外的任何东西。

In this case what you want is to pass a copy of the underlying object. Cloning the object is the only recourse. Your clone method needs a bit of an update though

在这种情况下,您想要的是传递底层对象的副本。克隆对象是唯一的办法。你的克隆方法需要一些更新

function ShallowCopy(o) {
  var copy = Object.create(o);
  for (prop in o) {
    if (o.hasOwnProperty(prop)) {
      copy[prop] = o[prop];
    }
  }
  return copy;
}

回答by Brett Weber

As a consideration to jQuery users, there is also a way to do this in a simple way using the framework. Just another way jQuery makes our lives a little easier.

作为对 jQuery 用户的考虑,还有一种方法可以使用该框架以简单的方式执行此操作。jQuery 让我们的生活变得更轻松的另一种方式。

var oShallowCopy = jQuery.extend({}, o);
var oDeepCopy    = jQuery.extend(true, {}, o); 

references :

参考 :

回答by Abubakar Ahmad

Actually, Javascript is always pass by value. But because object references are values, objects will behave like they are passed by reference.

实际上,Javascript 总是按值传递。但是因为对象引用是,所以对象的行为就像通过引用传递一样。

So in order to walk around this, stringifythe object and parseit back, both using JSON. See example of code below:

因此,为了解决这个问题,请使用 JSON对对象进行字符串化并将其解析回来。请参阅下面的代码示例:

var person = { Name: 'John', Age: '21', Gender: 'Male' };

var holder = JSON.stringify(person);
// value of holder is "{"Name":"John","Age":"21","Gender":"Male"}"
// note that holder is a new string object

var person_copy = JSON.parse(holder);
// value of person_copy is { Name: 'John', Age: '21', Gender: 'Male' };
// person and person_copy now have the same properties and data
// but are referencing two different objects

回答by Geetanshu Gulati

use obj2 = { ...obj1 } Now both objects have same value bust different reference

使用 obj2 = { ...obj1 } 现在两个对象都有相同的值,但引用不同