3
\$\begingroup\$

I'm looking for a review of the Javascript code which has this specifications:

Given two objects, the function "extend" adds properties from the 2nd object to the 1st object.

Notes:

  • Add any keys that are not in the 1st object.
  • If the 1st object already has a given key, ignore it (do not overwrite the property value).
  • Do not modify the 2nd object at all.

A runnable version can be found on repl.it.

function extend(obj1, obj2) {
  for (var key in obj2) {
    if (!obj1.hasOwnProperty(key)) {
      obj1[key] = obj2[key];
    }
  }
}
var obj1 = {
  a: 1,
  b: 2
};
var obj2 = {
  b: 4,
  c: 3
};

extend(obj1, obj2);

console.log(obj1); // --> {a: 1, b: 2, c: 3}
console.log(obj2); // --> {b: 4, c: 3}
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

One could also use the in operator instead of Object.hasOwnProperty().

One must ask: do inherited properties count? For simple objects (like the examples obj1 and obj2) it seems to not matter, but for more complex objects it will matter...

If in can be used, then it may provide better performance.

function extend(obj1, obj2) {
  for (var key in obj2) {
    if (!(key in obj1)) {
      obj1[key] = obj2[key];
    }
  }
}
var obj1 = {
  a: 1,
  b: 2
};
var obj2 = {
  b: 4,
  c: 3
};

extend(obj1, obj2);

console.log(obj1); // --> {a: 1, b: 2, c: 3}
console.log(obj2); // --> {b: 4, c: 3}

P.S.

It is a shame that Object.assign() doesn't have an option to not overwrite existing properties... if it did, then the extend function could simply utilize that function...

\$\endgroup\$
2
  • \$\begingroup\$ You have to be very careful with JSpref or you end up measuring the speed of code not actually executed. Optimizer will skip code that does not create a result. Try this one (uses soak to ensure execution) jsperf.com/testin-bm67 not much between them but hasownProperty has a slight advantage over in (Chrome) \$\endgroup\$
    – Blindman67
    May 16, 2018 at 23:02
  • \$\begingroup\$ Thanks @blindman67 - I have created a separate test for this case... \$\endgroup\$ May 16, 2018 at 23:30
3
\$\begingroup\$

Assuming that if the first object has a property set to undefined and the rule states no change then your code is almost spot on.

Some minor changes

  • The variable key into a const.
  • Return the extended object.
  • Vet the arguments.

Thus

function extend(obj1, obj2) {
    if (obj1 !== null && typeof obj1 === "object") {
        if (obj2 !== null && typeof obj2 === "object") {
            for (const key in obj2) { 
                if (!obj1.hasOwnProperty(key)) {
                    obj1[key] = obj2[key];
                }
            }
        }
    }
    return obj1;
}
extend({a: 1, b: undefined}, {b: 1, c: 2}); // returns {a: 1, b: undefined, c: 2}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.