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}
2 Answers 2
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...
-
\$\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 buthasownProperty
has a slight advantage overin
(Chrome) \$\endgroup\$Blindman67– Blindman672018年05月16日 23:02:33 +00:00Commented May 16, 2018 at 23:02 -
\$\begingroup\$ Thanks @blindman67 - I have created a separate test for this case... \$\endgroup\$2018年05月16日 23:30:57 +00:00Commented May 16, 2018 at 23:30
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 aconst
. - 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}