W dniu dzisiejszym Backbone.js zaskoczył mnie kolejny raz. Niestety tym razem negatywnie...

Właściwości
Tworzenie "klas", które dziedziczą po sobie właściwości jest czym naturalnym w Backbone. Nadpisywanie tychże właściwości jest równie proste. Przykład:
var AbstractWidget = Backbone.View.extend({
template: "foo.html"
});
var MenuWidget = AbstractWidget.extend({
template: "bar.html"
});
var v = new MenuWidget();
v.template; // bar.html
Niestety, takie działanie jest tylko do właściwości prymitywnych.
Problem
Inaczej sytuacja wygląda gdy mamy do czynienia z obiektami:
var AbstractWidget = Backbone.View.extend({});
var MenuWidget = AbstractWidget.extend({
templateParams: {},
initialize: function () {
this.templateParams.id = _.uniqueId();
}
});
var x = new MenuWidget();
var v = new MenuWidget();
x.templateParams.id; // 2
v.templateParams.id; // 2
Co ciekawe... gdy zamienimy kolejność wywołania ostatnich linijek:
var x = new MenuWidget();
x.templateParams.id; // 1
var v = new MenuWidget();
v.templateParams.id; // 2
// Ale gdy uruchamiamy następującą linię:
x.templateParams.id; // 2
Rozwiązanie
Problemy leży o podnóża działań JavaScript.
var AbstractWidget = Backbone.View.extend({});
var MenuWidget = AbstractWidget.extend({
templateParams: {},
initialize: function () {
// czyścimy obiektowe właściwości
this.templateParams = {};
this.templateParams.id = _.uniqueId();
}
});
var x = new MenuWidget();
var v = new MenuWidget();
x.templateParams.id; // 1
v.templateParams.id; // 2
Przedstawiam 2 bardzo ważne zasady programowaniu w JavaScript:
- Wartości prymitywne
string, number, boolean, null, undefined
są przekazywane przez wartość. - Wartości obiektowe przez referencję!