0

I noticed a strange behavior for Object.assign in the following case.

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"}]));

The output is

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

Rather than

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

When the forEach is changed to for, the output is as expected

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"}]));

Any explanation?

JackOrJones
  • 304
  • 1
  • 6
  • 15

4 Answers4

0

First, your function doesn't return anything. Not returning anything is essentially returning undefined.

Next, even if you return the value of a forEach call, forEach returns undefined.

Lastly, forEach also does not support breaking using a return. forEach will run for each item in the array. Your return inside forEach has no meaning, except for short-circuiting the callback at that iteration only.

Joseph
  • 117,725
  • 30
  • 181
  • 234
0

forEach doesn't return you anything, the inner return in forEach has no meaning. You can make use of map to return value like

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"}]));

or use a callback

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

func1(0, [{"key1": "value1", "key2": "value2"}], myCallback);
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
0

you may want a bit shorter code that completely avoids the forEach:

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

You dont need to iterate over an Array and break at a certain index, you can simply access this element using bracket notation...

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

Since you are looking for a specific index and not a property value or anything, you can very simply access the object you want from the list by saying list[idx].

You should also consider swapping the order of your Object.assign() parameters, because it will overwrite properties from right to left. If list[idx] already has a key3, it will not assign it to the new value. Putting {"key3": "value3"} in the far right of the parameter list of Object.assign()ensures that value will get written to the object.

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"}]));
mhodges
  • 10,938
  • 2
  • 28
  • 46