我注意到调用.map()而不将其分配给变量会使它返回整个数组,而不仅仅是返回更改后的属性:
const employees = [{
name: "John Doe",
age: 41,
occupation: "NYPD",
killCount: 32,
},
{
name: "Sarah Smith",
age: 26,
occupation: "LAPD",
killCount: 12,
},
{
name: "Robert Downey Jr.",
age: 48,
occupation: "Iron Man",
killCount: 653,
},
]
const workers = employees.concat();
workers.map(employee =>
employee.occupation == "Iron Man" ? employee.occupation = "Philantropist" : employee.occupation
);
console.log(employees);
但是考虑到.concat()创建了原始数组的副本并将其分配给worker,为什么雇员也会发生变异?
答案 0 :(得分:1)
之所以会这样,是因为数组中的对象仍被相同的指针引用。 (您的数组仍引用内存中的相同对象)。另外,Array.prototype.map()
总是返回一个数组,并且它的结果应该分配给一个变量,因为它不进行就地映射。在map
方法中更改对象的属性时,应考虑改用.forEach()
,以在复制的employees数组中修改对象的属性。要复制员工数组,可以使用以下命令:
const workers = JSON.parse(JSON.stringify(employees));
请参见以下示例:
const employees = [
{
name: "John Doe",
age: 41,
occupation: "NYPD",
killCount: 32,
},
{
name: "Sarah Smith",
age: 26,
occupation: "LAPD",
killCount: 12,
},
{
name: "Robert Downey Jr.",
age: 48,
occupation: "Iron Man",
killCount: 653,
},
]
const workers = JSON.parse(JSON.stringify(employees));
workers.forEach(emp => {
if(emp.occupation == "Iron Man") emp.occupation = "Philantropist";
});
console.log("--Employees--")
console.log(employees);
console.log("\n--Workers--");
console.log(workers);
答案 1 :(得分:1)
workers = workers.map(employee => employee.occupation == "Iron Man" ? (employee.occupation = "Philantropist", employee) : (employee.occupation, employee) );
[...]为什么员工也会发生变异?
{array.map()
使用array
中的每个元素调用传递的函数,并返回一个包含该函数返回的值的新数组。
您的函数只返回表达式的结果
element.baz = condition ? foo : bar;
根据情况,
foo
或bar
baz
和另外(expression1, expression2)
将对两个表达式求值并返回expression2
(请参见comma operator)。
因此,尽管在两种情况下均返回employee
,但是您仍使用左表达式(表达式1)来修改原始对象。
您可能想使用Object.assign()
array.map((employee) => Object.assign({ }, employee))
代替使用该array.concat()
“技巧”。使用该映射,您不仅可以创建一个新数组,还可以创建其属性已复制的新对象。尽管这不会“深度复制”嵌套的对象,例如{ foo: { ... } }
-通过属性foo
访问的对象仍然与原始对象相同。在这种情况下,您可能想看看其他答案中提到的深度复制模块。
答案 2 :(得分:0)
数组引用发生了变化,但是复制的数组仍然引用原始数组中的原始对象。因此,阵列中对象的任何更改都会反映在阵列的所有副本中。除非您对数组进行深拷贝,否则内部对象中的某些更改可能会在每个拷贝中反映出来
What is the difference between a deep copy and a shallow copy?
深拷贝可以用几种方法制作。这篇文章专门讨论了:What is the most efficient way to deep clone an object in JavaScript?
答案 3 :(得分:0)
import { highlight } from "../constants/Colours.ios";
根据从回调返回的值构建一个新数组,可以轻松地使用它来克隆数组中的对象:
map
或者您可以深度克隆数组,然后使用简单的 const workers = employees.map(employee => ({
...employee, // take everything from employee
occupation: employee.ocupation == "Iron Man" ? "Philantropist" : employee.occupation
}));
对其进行突变:
for