问题描述
当您需要在javascript中复制对象时,这是关于最佳做法..
It's about best practices when you need to copy object in javascript..
例如:
我有一个对象 {name:'Dodo',method:function(){console.log(this.name)}}
;
我需要创建它的副本:
var obj = { name: 'Dodo', method: function () { console.log(this.name) } };
// what is better?
var copyUnderscore = _(obj).clone();
var copySimple = obj;
有什么更好的方法?谢谢!
What is the better way? Thanks!
推荐答案
_。clone
与赋值完全不同。
_。clone
创建一个新对象并将每个值从原始对象复制到新对象。
_.clone
creates a new object and copies each value from the original to the new object.
赋值只是将变量指向已存在的对象。
An assignment just points a variable at the object that already exists.
假设你有一只小狗。让我们称他为雷克斯。
Suppose you had a puppy. Let's call him Rex.
如果你和某人讨论雷克斯,你会称他为雷克斯,或者也许是狗。这两个都是对有关动物的引用。作业类似于为您的宠物使用不同的短语:
If you're discussing Rex with someone you'll call him Rex, or perhaps "the Dog". Both of those are references to the animal in question. An assignment is analogous to using different phrases for your pet:
rex = {
type: 'Dog',
age: '12 Weeks',
name: "Rex",
fixed: false,
fix: function() {
this.fixed = true;
console.log(this.name + " Fixed.");
}
};
theDog = rex;
// Note the use of `===`, which checks for object identity.
// Assignment (as above) is the whole point of `===`
if (theDog === rex) {
alert("The Dog is the Same as Rex");
}
当你改变一个关于一个的东西时,它会改变两个引用。所以假设你修复Rex:
When you change something about one, it changes for both references. So suppose you "fix" Rex:
rex = {
type: 'Dog',
age: '12 Weeks',
name: "Rex",
fixed: false,
fix: function() {
this.fixed = true;
console.log(this.name + " Fixed.");
}
};
theDog = rex;
rex.fix();
alert("The Dog is " + (theDog.fixed ? "" : "not ") + "fixed");
alert("Rex is " + (rex.fixed ? "" : "not ") + "fixed");
theDog
也是固定的。
现在假设您已经克隆了Rex。 (让我们为了争论而假装他还没有修好)。
Now suppose you had Rex cloned. (Let's pretend he's not fixed yet for the sake of argument).
rex = {
type: 'Dog',
age: '12 Weeks',
name: "Rex",
fixed: false,
fix: function() {
this.fixed = true;
console.log(this.name + " Fixed.");
}
};
theDog = rex;
otherDog = _.clone(rex);
console.log(theDog);
console.log(rex);
console.log(otherDog);
var message = rex === theDog ? "Rex is the same as the dog" : "Rex and the dog are different";
message += "\n";
message += rex === otherDog ? "Rex is the same as the other dog" : "Rex is different from the other dog";
message += "\n";
message += rex.fixed ? "Rex is fixed" : "Rex is not fixed";
message += "\n";
message += otherDog.fixed ? "Other dog is fixed" : "Other dog is not fixed";
alert(message);
otherDog.fix();
message = rex.fixed ? "Rex is fixed" : "Rex is not fixed";
message += "\n";
message += otherDog.fixed ? "Other dog is fixed" : "Other dog is not fixed";
alert(message);
<script src="http://underscorejs.org/underscore-min.js"></script>
rex
中的每个值都已复制到 otherDog
。奇迹般地,otherDog出生于12周岁。但修复一个将不修复另一个。
Each value from rex
has been copied into otherDog
. Miraculously, "otherDog" was born at age 12 weeks. But fixing one will not fix the other.
现在,因为 rex
和 theDog
是同一只狗,都没有固定。但是, otherDog
已修复。他是一个克隆人,而不是同一种动物。
Now since rex
and theDog
are the same dog, neither are fixed. However, otherDog
is fixed. He is a clone, not the same animal.
有一些细微之处需要注意。 _。clone
不会深深复制。这意味着克隆对象中任何值的任何对象或数组都会被赋值复制到新对象(请参阅第一个片段以查看其含义)。
There are some subtleties to beware of. _.clone
does not copy deeply. This means that any object or array that is a value in the cloned object is copied by assignment to the new object (See the first snippet for a review of what that means).
这意味着如果 rex
有一个属性母
这是一个代表他的对象妈妈,它将在 rex
和 otherDog
之间共享。对 rex
的母亲的任何更改都会传播到 otherDog
。这与现实生活没有什么不同;亲生母亲是同一个。
This means that if rex
had a property mother
that was an object representing his mother it would be shared between rex
and otherDog
. Any changes to rex
's mother would be propagated to otherDog
. This is not that different from real life; the biological mother is one and the same.
编辑
另一个奇迹注意:克隆一只固定的狗会产生另一只固定的狗。这就是生物学比喻崩溃的地方。
As another miraculous note: cloning a fixed dog produces another fixed dog. This is where the biological metaphor breaks down.
再次编辑(2018年6月)
这个问题的读者可能会对两个额外的ES6功能感兴趣:
There are two additional ES6 pieces of functionality that might be of interest to readers of this question:
以下内容与 _。clone
相同(复制成员):
The following is the same as _.clone
(copies members):
让x = {... rex};
以下将成员复制到现有对象,然后返回该对象:
The following copies members to an existing object, and then returns that object:
let x = {};
let anotherReferenceToX = Object.assign(x,rex);
奖金!
值得注意的是,。您还可以使用 function(x){return JSON.parse(JSON.stringify(x))}
。但是这会引起循环引用,并且lodash不会。
It's worth noting that lodash actually has a deep clone operation. You can also use function (x) { return JSON.parse(JSON.stringify(x)) }
. But that will choke on circular references, and lodash will not.
这篇关于下划线clone()和简单'='之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!