javascript 下划线 clone() 和简单的 '=' 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16961898/
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
What's the difference between underscore clone() and simple '='?
提问by Kosmetika
It's about best practices when you need to copy object in javascript..
当您需要在 javascript 中复制对象时,这是关于最佳实践的。
For example:
例如:
I have an object { name: 'Dodo', method: function () { console.log(this.name) }}
;
我有一个对象{ name: 'Dodo', method: function () { console.log(this.name) }}
;
I need to create a copy of it:
我需要创建它的副本:
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!
什么是更好的方法?谢谢!
回答by Chris Pfohl
_.clone
is completely different from assignment.
_.clone
和赋值完全不同。
_.clone
creates a new object and copies each value from the original to the new object.
_.clone
创建一个新对象并将每个值从原始对象复制到新对象。
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,您会称他为 Rex,或者可能是“狗”。这两个都是对所讨论的动物的引用。作业类似于为您的宠物使用不同的短语:
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");
}
When you change something about one, it changes for both references. So suppose you "fix" Rex:
当您更改一个的某些内容时,它会更改两个引用。所以假设你“修复”了 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
is also fixed.
theDog
也是固定的。
Now suppose you had Rex cloned. (Let's pretend he's not fixed yet for the sake of argument).
现在假设您克隆了 Rex。(为了争论,我们假设他还没有固定好)。
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>
Each value from rex
has been copied into otherDog
. Miraculously, "otherDog" was born at age 12 weeks. But fixing one will notfix the other.
来自的每个值rex
都已复制到otherDog
. 奇迹般地,“otherDog”在 12 周大时出生。但是修复一个不会修复另一个。
Now since rex
and theDog
are the same dog, neither are fixed. However, otherDog
isfixed. He is a clone, not the same animal.
现在因为rex
和theDog
是同一条狗,两者都不是固定的。然而,otherDog
是固定的。他是克隆人,不是同一种动物。
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 assignmentto the new object (See the first snippet for a review of what that means).
有一些微妙之处需要注意。 _.clone
复制不深。这意味着作为克隆对象中值的任何对象或数组都通过赋值复制到新对象(请参阅第一个片段以了解其含义)。
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.
这意味着如果rex
有一个属性mother
是代表他母亲的对象,它将在rex
和之间共享otherDog
。对rex
的母亲所做的任何更改都将传播到otherDog
。这与现实生活没有什么不同;生母是一回事。
EDIT
编辑
As another miraculous note: cloning a fixed dog produces another fixed dog. This is where the biological metaphor breaks down.
作为另一个奇迹:克隆一条固定的狗会产生另一条固定的狗。这就是生物隐喻崩溃的地方。
EDIT AGAIN (June 2018)
再次编辑(2018 年 6 月)
There are two additional ES6 pieces of functionality that might be of interest to readers of this question:
这个问题的读者可能会感兴趣另外两个 ES6 功能:
Object Splat
物体飞溅
The following is the same as _.clone
(copies members):
以下同_.clone
(副本成员):
let x = {...rex};
let x = {...rex};
Object.assign
对象分配
The following copies members to an existing object, and then returns that object:
以下将成员复制到现有对象,然后返回该对象:
let x = {};
let anotherReferenceToX = Object.assign(x, rex);
let x = {};
let anotherReferenceToX = Object.assign(x, rex);
BONUS!
奖金!
It's worth noting that lodash actually hasa 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.
值得注意的是,lodash 实际上有一个深度克隆操作。您也可以使用function (x) { return JSON.parse(JSON.stringify(x)) }
. 但这会阻塞循环引用,而 lodash 不会。