I’ve been reading “Javascript: The Good Parts” by Douglas Crockford – and while it’s a bit extreme, I’m on board with a lot of what he has to say.
In chapter 3, he discusses objects and at one point lays out a pattern (also found here) for simplifying & avoiding some of the confusion/issues that come with the use of the built-in “new” keyword.
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
newObject = Object.create(oldObject);
So I’ve tried using this in a project I’m working on, and I noticed an issue when attempting to inherit from objects that are nested. If I overwrite a value of a nested object inherited using this pattern, it overwrites the nested element all the way up the prototype chain.
Crockford’s example is like the flatObj in the following example, which works well. The behaviour, however, is inconsistent with nested objects:
var flatObj = {
firstname: "John",
lastname: "Doe",
age: 23
}
var person1 = Object.create(flatObj);
var nestObj = {
sex: "female",
info: {
firstname: "Jane",
lastname: "Dough",
age: 32
}
}
var person2 = Object.create(nestObj);
var nestObj2 = {
sex: "male",
info: {
firstname: "Arnold",
lastname: "Schwarzenneger",
age: 61
}
}
var person3 = {
sex: "male"
}
person3.info = Object.create(nestObj2.info);
// now change the objects:
person1.age = 69;
person2.info.age = 96;
person3.info.age = 0;
// prototypes should not have changed:
flatObj.age // 23
nestObj.info.age // 96 ???
nestObj2.info.age // 61
// now delete properties:
delete person1.age;
delete person2.info.age;
delete person3.info.age;
// prototypes should not have changed:
flatObj.age // 23
nestObj.info.age // undefined ???
nestObj2.info.age // 61
(also on a fiddle)
Am I doing something wrong, or is this a limitation of this pattern?
There is no inconsistency. Just don’t think of nested objects: a direct property of an object is always either on its prototype or an own property. It’s irrelevant wheter the property value a primitive or an object.
So, when you do
child.xwill be referencing the same object asparent.x– that one{a:0}object. And when you change a property of it:both will be affected. To change a “nested” property independently, you first will have to create an independent object:
What you can do is
which means they are not absolutely independent – but still two different objects.