简体   繁体   中英

Why does dot notation returns object with added properties while spread operator does not?

I have a function that returns a new object based on conditions. Why does when I use the dot notation it returns the new object while spread operator does not

This line returns the new object with new property


const newValue = values => {
 const condition = "SUCCESS"

 const result = values.filter(r => {
    if(condition === "SUCCESS"){
     r.codes = "Success Test"
     return r
    }
    r.codes = "Fail Test"
    return r     
 })

 return result
}

This line returns the old object without the new property


const newValue = values => {
 const condition = "SUCCESS"

 const result = values.filter(r => {
    if(condition === "SUCCESS"){
     return { ...r, codes: "Success Test" }
    }
    return { ...r, codes: "Fail Test" }  
 })

 return result
}

Expected result should be :

result = [{ name:"Hey", codes:"Success Test" }]

filter only cares if the function you pass to it returns a value that (can be coerced to something that) is true or false .

In both cases, you return an object. Objects are always true values, so the value in the original array is kept in the filtered array.

In your first example, the object you return is the original object which you modify.

In your second example, the object you return is a new object, so the original object is unmodified. Since filter only cases about true or false , it always returns the original object (which will only have a new property on it if you modify the original).


You always return a true value, and never return a false value, which makes using filter pointless.

It looks like you are trying to map the array, not filter it.

The .filter callback is meant to take an array, and create a new array which is the same as the old array, except with items removed based on a condition. Here, you're using .filter incorrectly, since you're both mutating the existing array items (with r.codes = assignments) and you're always returning an object from the .filter callback (and objects are always truthy, so every item in the original array will be present in the output array).

Because assigning to r.codes mutates the existing array, and because result will always be the original array (with the mutated items), assigning to r.codes results in a changed array.

When you spread into a new returned object, that object is checked for its truthyness (objects are truthy), and then discarded; the object is not used anywhere else.

If you want to mutate the existing objects, use forEach (which is the proper array method to use for side-effects only):

const newValue = values => {
  const condition = "SUCCESS"

  values.forEach(value => {
    value.codes = condition === "SUCCESS" ? "Success Test" : 'Fail Test';
  });
  return values;
}

If you don't want to mutate the existing objects, use .map and spread:

const newValue = values => {
  const condition = "SUCCESS"

  return values.map(value => ({
    ...value,
    codes: condition === "SUCCESS" ? "Success Test" : 'Fail Test'
  }));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM