了解for和forEach中的Object.assign行为

时间:2017-05-15 17:42:54

标签: javascript ecmascript-6

在下面的例子中,我注意到Object.assign有一个奇怪的行为。

function func1(idx, list) {
    list.forEach((item, i) => {
        if (i === idx) {
            console.log(Object.assign({}, {"key3": "value3"}, item));
            return Object.assign({}, {"key3": "value3"}, item); 
        }
    }); 
}

console.log(func1(0, [{"key1": "value1", "key2": "value2"}]));

输出

{
 "key3": "value3",
 "key1": "value1",
 "key2": "value2"
}
undefined

而不是

{
  "key3": "value3",
  "key1": "value1",
  "key2": "value2"
}
{
  "key3": "value3",
  "key1": "value1",
  "key2": "value2"
}

当forEach更改为for时,输出符合预期

function func2(idx, list) {
    for(let i = 0; i < list.length; i++){
        let item = list[i];
        if (i === idx) {
            console.log(Object.assign({}, {"key3": "value3"}, item));
            return Object.assign({}, {"key3": "value3"}, item); 
        }
    } 
}

console.log(func2(0, [{"key1": "value1", "key2": "value2"}]));

有任何解释吗?

4 个答案:

答案 0 :(得分:0)

首先,你的功能并没有返回任何东西。没有返回任何东西本质上是返回undefined

接下来,即使您返回forEach来电的值forEach returns undefined

最后,forEach也不支持使用返回功能。 forEach将针对数组中的每个项运行。你return里面的forEach没有任何意义,只是在那次迭代中短路回调。

答案 1 :(得分:0)

forEach并没有给你任何回报,forEach的内部回报没有任何意义。您可以使用map返回值,如

&#13;
&#13;
Parse failed: ''
Parse success: 'foo (a) = 3*8+a' -> foo(a, ) = syntax_tree
Parse success: 'bar (x, y) = (sin(x) + y*y) / (x + y)' -> bar(x, y, ) = syntax_tree
Parse failed: 'oops (x, y) = (sin(x) + y*y) / (x + a)'
Remaining unparsed: 'oops (x, y) = (sin(x) + y*y) / (x + a)'
&#13;
&#13;
&#13;

或使用回调

&#13;
&#13;
function func1(idx, list) {
    return list.map((item, i) => {
        if (i === idx) {
            console.log(Object.assign({}, {"key3": "value3"}, item));
            return Object.assign({}, {"key3": "value3"}, item); 
        }
    }); 
}

console.log(func1(0, [{"key1": "value1", "key2": "value2"}]));
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可能需要更短的代码来完全避免使用forEach:

func1=(i,list)=>Object.assign({key3:value3},list[i]||{});

你不需要迭代一个数组并在某个索引处中断,你只需使用括号表示法访问这个元素......

答案 3 :(得分:0)

由于您正在寻找特定索引而不是属性值或任何内容,因此您可以通过说Object.assign()来非常简单地从列表中访问所需对象。

您还应该考虑交换list[idx]参数的顺序,因为它会从右到左覆盖属性。如果key3已经有{"key3": "value3"},则不会将其分配给新值。将Object.assign()放在function func1(idx, list) { console.log(Object.assign({}, list[idx], {"key3": "value3"})); return Object.assign({}, list[idx], {"key3": "value3"}); } console.log(func1(0, [{"key1": "value1", "key2": "value2"}]));参数列表的最右侧可确保将值写入对象。

@Output