Hello,
Am 03.11.12 21:47, schrieb stephanos:
> I don't know if I'm doing something wrong but '/utils.beget
> attributes'/ seems to always return an empty object instead of
> undefined/null?
utils.beget returns an object that is empty BUT it has the given object
as its prototype. It’s a simple way to set up prototypal delegation
(sometimes called prototypal inheritance).
http://javascript.crockford.com/prototypal.html
In ECMAScript-5-capable browsers, utils.beget just uses Object.create
which is a built-in function for setting up prototypal inheritance.
https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object/create
The returned object is an empty wrapper which allows to access all
properties of the prototype:
var o1 = { prop: 1 };
var o2 = Object.create(o1);
// o2 has no own properties:
alert(_.isEmpty(o1) + ' ' + _.isEmpty(o2));
// -> true false
alert(o1.hasOwnProperty('prop') + ' ' + o2.hasOwnProperty('prop'));
// -> true false
// But you can read inherited properties:
alert(o1.prop + ' ' + o2.prop);
// -> 1 1
So the object o2 is empty but all of o1’s properties can be accessed by
their name.
We’re using this approach in getTemplateData so you can add and
overwrite some properties for the template safely without changing the
model attributes (create a “view model” out of the bare model
attributes). The standard Backbone approach is to create a copy of the
model attributes but this is significantly slower and does not scale.
In practice, you shouldn’t see a difference between the actual model
attributes and the wrapper that delegates to the model data.
Just make sure that you don’t skip inherited properties when looping
over all object properties.
// Usually a loop performs a hasOwnProperty check:
for (var propName in o2) {
if (o2.hasOwnProperty(propName)) {
alert(propName + ': ' + o2[propName]);
}
}
// -> Won’t alert anything
// Without the check:
for (var propName in o2) {
alert(propName + ': ' + o2[propName]);
}
// -> prop: 1, because it walks up the prototype chain
Helpers like Underscore’s _.each, jQuery’s $.each etc. perform this check.
But usually a template doesn’t need to loop over all properties.
Regards
Mathias