将对象作为参数传递时,JavaScript会通过引用传递它们,并且很难创建对象的本地副本.
var o = {};
(function(x){
var obj = x;
obj.foo = 'foo';
obj.bar = 'bar';
})(o)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
o不会有.foo或.bar.
use*_*716 57
并不是的.
根据您的实际需要,一种可能性是设置o为新对象的原型.
var o = {};
(function(x){
var obj = Object.create( x );
obj.foo = 'foo';
obj.bar = 'bar';
})(o);
alert( o.foo ); // undefined
Run Code Online (Sandbox Code Playgroud)
因此,您添加的任何属性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'
Run Code Online (Sandbox Code Playgroud)
在这里,你可以看到,因为你没影的阵列,在baz上o一个baz物业obj,该o.baz数组被修改.
所以相反,你需要先遮蔽它:
var o = {
baz: []
};
(function(x){
var obj = Object.create( x );
obj.baz = [];
obj.baz.push( 'new value' );
})(o);
alert( o.baz[0] ); // undefined
Run Code Online (Sandbox Code Playgroud)
Pau*_*ese 35
这是克隆函数,它将执行对象的深层复制:
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;
}
Run Code Online (Sandbox Code Playgroud)
现在你可以像这样使用:
(function(x){
var obj = clone(x);
obj.foo = 'foo';
obj.bar = 'bar';
})(o)
Run Code Online (Sandbox Code Playgroud)
svi*_*mre 35
看看这个答案/sf/answers/374085211/.
简而言之,JSON.parse(JSON.stringify(obj))如果您的对象可以序列化为json,则可以快速复制对象.
Bra*_*don 20
使用 Object.assign()
例:
var a = {some: object};
var b = new Object;
Object.assign(b, a);
// b now equals a, but not by association.
Run Code Online (Sandbox Code Playgroud)
一个更清洁的例子做同样的事情:
var a = {some: object};
var b = Object.assign({}, a);
// Once again, b now equals a.
Run Code Online (Sandbox Code Playgroud)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
And*_*y E 15
你对JavaScript中的对象如何工作有点困惑.对象的引用是变量的值.没有反序列化的价值.创建对象时,其结构存储在内存中,并且为其分配的变量保存对该结构的引用.
即使你所要求的是某种简单的本地语言结构,它在技术上仍然是克隆.
JavaScript实际上只是按值传递...它只是传递的值可能是对某事物的引用.
小智 13
用这个
x = Object.create(x1);
Run Code Online (Sandbox Code Playgroud)
x并且x1将有两个不同的对象,改变x也不会改变x1
Javascript总是按值传递.在这种情况下,它将引用的副本传递给o匿名函数.代码正在使用引用的副本,但它正在改变单个对象.没有办法让javascript通过除value之外的任何东西.
在这种情况下,您想要的是传递底层对象的副本.克隆对象是唯一的办法.您的克隆方法需要一些更新
function ShallowCopy(o) {
var copy = Object.create(o);
for (prop in o) {
if (o.hasOwnProperty(prop)) {
copy[prop] = o[prop];
}
}
return copy;
}
Run Code Online (Sandbox Code Playgroud)
作为jQuery用户的考虑因素,还有一种方法可以使用框架以简单的方式完成此操作.换句话说,jQuery让我们的生活变得更轻松.
var oShallowCopy = jQuery.extend({}, o);
var oDeepCopy = jQuery.extend(true, {}, o);
Run Code Online (Sandbox Code Playgroud)
参考:
实际上,Javascript总是按值传递.但是因为对象引用是值,所以对象的行为就像它们通过引用传递一样.
因此,为了遍历这个,使用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
Run Code Online (Sandbox Code Playgroud)
ES6
使用像obj2 = { ...obj1 }
Will 一样的扩展运算符会有相同的值但不同的引用
ES5
使用 Object.assignobj2 = Object.assign({}, obj1)
| 归档时间: |
|
| 查看次数: |
96827 次 |
| 最近记录: |