objects contain same values but shouldn't
They should, because you haven't changed the options
property on variation
, so it still points at the same object that the original.options
points to.
When you do this:
var original = {
options: {
value: null,
factor: 13
},
init: function (container) {
this.options.value = container.getAttribute('data-value');
}
};
Here's what you get in memory (some details omitted):
+????????????????????+
+????????????+ +???>| (Object.prototype) |<?+
original???>| (object) | | +????????????????????+ |
+????????????+ | |
| __proto__ |???+ +?????????????+ |
| options |???????>| (object) | |
| init |???+ +?????????????+ |
+????????????+ | | __proto__ |?????????+
| | value: null |
| | factor: 13 |
| +?????????????+
|
| +????????????+
+????| (function) |
+????????????+
...where __proto__
is a pseudo-property showing what the object's prototype is (specifically, the value of what the spec calls the object's internal [[Proto]]
property). (On browsers, in ES2015, there is actually a __proto__
accessor, but it shouldn't be used.)
Then when you do this:
var variation = Object.create(original);
You have:
+????????????+
variation??>| (object) |
+????????????+
| __proto__ |??+
+????????????+ |
|
+??????????????????+ +????????????????????+
| +?>| (Object.prototype) |<?+
+????????????+ | +????????????????????+ |
original???>| (object) | | |
+????????????+ | |
| __proto__ |?????+ +?????????????+ |
| options |???????>| (object) | |
| init |???+ +?????????????+ |
+????????????+ | | __proto__ |?????????+
| | value: null |
| | factor: 13 |
| +?????????????+
|
| +????????????+
+????| (function) |
+????????????+
You can see how both original
and variation
are still pointing at the same options object.
If you want separate options objects, you have to create a new object. You could make variation.options
use original.options
as its prototype:
var variation = Object.create(original);
variation.options = Object.create(original.options);
...but then you'd have to do it again for firstDiv
and secondDiv
:
var firstDiv = Object.create(variation);
firstDiv.options = Object.create(variation.options);
var secondDiv = Object.create(variation);
secondDiv.options = Object.create(variation.options);
...which suggests we need to do something different.
You could have a function you use to do it:
function createVariation(source) {
var v = Object.create(source);
v.options = Object.create(source.options);
return v;
}
var variation = createVariation(original);
var firstDiv = createVariation(variation);
var secondDiv = createVariation(variation);
...but you might look at constructor functions or maker functions, and a fairly typical pattern called the "extend" function (such as jQuery's or Underscore's).