Przejdź do treści

Backbone.js: problem z unikalnymi właściwościami obiektowymi

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

Baner promujący artykuł

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ę!