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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 06:36:29  来源:igfitidea点击:

What's the difference between underscore clone() and simple '='?

javascriptobjectunderscore.js

提问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

_.cloneis completely different from assignment.

_.clone和赋值完全不同。

_.clonecreates 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");

theDogis 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 rexhas 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 rexand theDogare the same dog, neither are fixed. However, otherDogisfixed. He is a clone, not the same animal.

现在因为rextheDog是同一条狗,两者都不是固定的。然而,otherDog固定的。他是克隆人,不是同一种动物。

There are some subtleties to beware of. _.clonedoes 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 rexhad a property motherthat was an object representing his mother it would be shared between rexand 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 不会。