数组的 _.map 和 _.clone 有什么区别?

What's the difference between _.map and _.clone with arrays?

我有一组对象。我需要知道这两行之间的区别:

var clonedObj = _.map(obj, _.clone);

还有这个:

var clonedObj = _.clone(obj);

最终两者return是一回事。谁能给我解释一下区别?

不同之处在于,在带有 _.map 的第一个代码片段中,您将 _.clone 应用于 该数组的每个元素 -- 将每个元素映射到一个新的克隆对象。这意味着对象是一个一个地浅克隆的,因此它们彼此不相等,这意味着它们在内存中是不同的对象:

const arr = [
  { foo: 'bar' }
];

console.log(_.map(arr, _.clone)[0] == arr[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

另一方面,如果你只克隆数组,它会浅克隆数组,但数组中的元素保持不变,因此克隆的对象数组与原始数组具有相同的引用:

const arr = [
  { foo: 'bar' }
];
console.log(_.clone(arr)[0] == arr[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

在内部,_.clone 方法使用 structured clone algorithm defined in the HTML5 specification

按照 underscore.js

的官方文档

1) 克隆

_.clone(object) 

克隆函数用于创建传递对象的浅表副本。 数组元素被浅层复制,这意味着数组元素不会为新数组复制,而是在新克隆的数组中传递或使用对现有元素的引用。

2) 地图

_.map(list, iteratee, [context])

通过转换函数 (iteratee) 映射列表中的每个值来生成新的值数组。 iteratee 被传递了三个参数:值,然后是迭代的索引(或键),最后是对整个列表的引用。

                 **var clonedObj = _.map(obj, _.clone);**

_.map 创建新的内存位置,其中 _.clone 函数用于将元素浅拷贝到新位置。

实际上,obj 是在新的内存位置创建的。

                **var clonedObj = _.clone(obj);**

在这种情况下,返回浅拷贝对象意味着传递 obj 中项目的引用以创建新的克隆对象。 clonedObj 中的项目包含对 obj 中项目的引用。

参考:http://underscorejs.org/