I have the following nested data structure:
{ x: { y: 'foo', z: 'bar' } }
This data is stored on the prototype of the object, which is the parent of both specific objects and other prototypes.
I want to assign a property x.y
to inherit objects without affecting the parent prototype. In addition, I want access to x.z
be delegated to the prototype.
What is the best way to do this?
Here is an executable snippet that better illustrates what I want to accomplish:
var prototype = {
question: 'Am I nested?',
nested: {
answer: 'Yes.',
thoughts: 'I like being nested.'
}
};
var liar = Object.create(prototype);
liar.nested.answer = 'N-No...!';
var indecisive = Object.create(prototype);
indecisive.nested = { answer: 'I dunno?' };
function results(text) { results.element.appendChild(document.createTextNode(text + '\n')); }; results.element = document.getElementById('results'); results.json = function() { for(var i = 0, len = arguments.length; i < len; ++i) { results(JSON.stringify(arguments[i], results.json.replacer, results.json.indentation)); } }; results.json.replacer = function(k, v) { return typeof v === 'undefined' ? 'undefined' : v; }; results.json.indentation = 4;
results.json(
prototype.nested.answer,
liar.nested.answer,
indecisive.nested.answer,
prototype.nested.thoughts,
liar.nested.thoughts,
indecisive.nested.thoughts,
prototype,
liar,
indecisive
);
<html>
<body>
<pre id="results"></pre>
</body>
</html>
Run codeHide resultThis question is complex because the property nested
refers to the same object both in the prototype and in the objects associated with it. If I assign object.nested.answer
, it changes object.nested
which is the same object that it refers to prototype.nested
.
. , . object.nested.answer
object
.
object.nested
. , object
, object.nested.thoughts
. , , prototype.nested.thoughts
.
. prototype.nested.thoughts
, , object
; nested.thoughts
.
, , . ? , ?
,
. , API, , , , , , , , , , , - .
:
- . ,
tuple
. tuple
s.
โโโโโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Abstraction โ Pair โ Description โ
โโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Coordinates โ (x, y) โ Cartesian coordinates. โ
โ Dimensions โ (w, h) โ Width and height. โ
โโโโโโโโโโโโโโโดโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโ
, .
- ,
toString
prototype
. (x, y)
, tuple
.dimensions
|w, h|
.:
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Abstraction โ Notation โ Grammar โ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Tuple โ (xโ, xโ, ... , xแตข) โ '(' element ( ', ' element )* ')' โ
โโโโโโโโโโโโโโโชโโโโโโโโโโโโโโโโโโโโโชโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโก
โ Coordinates โ (x, y) โ Inherits the grammar of Tuple. โ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Dimensions โ |w, h| โ '|' element ( ', ' element )* '|' โ
โโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
var tuple = {
prototype: {
toString: function tuple_toString() {
return '(' + this.elements.join(', ') + ')';
}
},
new: function tuple_new() {
var tuple = Object.create(this.prototype);
tuple.elements = Array.prototype.slice.call(arguments);
return tuple;
}
};
var coordinates = {
prototype: Object.create(tuple.prototype),
new: tuple.new
};
var dimensions = {
prototype: Object.create(tuple.prototype),
new: tuple.new
};
tuple.prototype.toString = function tuple_toString() {
var elements = this.elements,
notation = this.notation,
join = notation.join
brackets = notation.brackets,
open = brackets.open,
close = brackets.close;
return open + elements.join(join) + close;
};
tuple.prototype.notation = {
brackets: {
open: '(',
close: ')'
},
join: ', '
};
dimensions.prototype.notation = {
brackets: {
open: '|',
close: '|'
}
};
function results(text) { results.element.appendChild(document.createTextNode(text + '\n')); }; results.element = document.getElementById('results'); results.json = function() { for(var i = 0, len = arguments.length; i < len; ++i) { results(JSON.stringify(arguments[i], results.json.replacer, results.json.indentation)); } }; results.json.replacer = function(k, v) { return typeof v === 'undefined' ? 'undefined' : v; }; results.json.indentation = 4;
var triplet = tuple.new(1, 2, 3);
var origin = coordinates.new(0, 0);
var fullHD = dimensions.new(1920, 1080);
results.json(
triplet.toString(),
origin.toString(),
fullHD.toString(),
triplet.notation.join,
origin.notation.join,
fullHD.notation.join
);
<html>
<body>
<pre id="results"></pre>
</body>
</html>
Hide resultfullHD.notation.join
undefined
. Array.prototype.join
, , , .
, tuple.prototype.notation.join
, ', '
.