初始化时,Backbone不会休息属性值

时间:2015-01-09 03:50:08

标签: javascript backbone.js underscore.js

我刚刚发现Backbone在创建新实例时不重置属性值(仅适用于对象和数组)。我创建了一个简单的JSFiddle(http://jsfiddle.net/samitha/fb5chvbv/)来演示这种行为。仔细观察后会发生这种情况,因为骨干处理原型链的方式。

tmpI: 0,
tmpO: {
    t: 0
},
tmpA: [0],
创建新实例时,

以下对象中的值不会重置。第一次运行 我,O& A will = 0.当重新创建一个新实例时,值为I = 0但是O& A = 2.

2 个答案:

答案 0 :(得分:1)

在javascript中,原型值在实例之间共享。 对象和数组是可变的,这意味着更改嵌套值将改变原型上的原始对象,并且不会设置实例级别。

长话短说,经验法则是在原型上设置方法,在实例级别设置数据。

如果您想要唯一值,请在实例级别而不是原型上设置它们。

你需要的是这样的东西:

var BaseView = Backbone.View.extend({
    el: $('#root'),
    initialize: function () {
        console.log('init::BaseView');
        this.tmpI = 0
        this.tmpO = {t: 0}
        this.tmpA = [0],
    },
    baseViewMethod: function () {
        console.log('a base view method');
    },
    spinnerToggleFunctions: {}, //function () { return {} },

    preRender: function () {
        console.log('*** I: %o O: %o A: %o', this.tmpI, this.tmpO.t, this.tmpA[0]);
        this.tmpI = 1;
        this.tmpO.t = 1;
        this.tmpA[0] = 1;
        //this.spinnerToggleFunctions[new Date()]=1;
        //console.log('*** %o', this.spinnerToggleFunctions);
        //this.spinnerToggleFunctions={};
    },

    postRender: function () {
        console.log('*** I: %o O: %o A: %o', this.tmpI, this.tmpO.t, this.tmpA[0]);
        this.tmpI = 2;
        this.tmpO.t = 2;
        this.tmpA[0] = 2;
    },

    render: function () {
        this.preRender();
        this.$el.html("Time"+ new Date().toJSON());
        this.postRender();
    },
    destroy: function () {
        this.remove();
        this.unbind();
    }
});

答案 1 :(得分:0)

这实际上不是Backbone.js的问题。

spinnerToggleFunctions: {}, //function () { return {} },
tmpI: 0,
tmpO: {
    t: 0
},
tmpA: [0]

您可能知道这一点,但您示例中上面代码中的tmpI,tmpO and tmpA是BaseView的属性,将通过proto从其实例中访问。

当你

    this.tmpI = 1;
    this.tmpO.t = 1;
    this.tmpA[0] = 1;

你正在this.tmpI创建实例新属性,所以现在实例有自己的属性tmpI,这意味着它不必检查__proto__是否有一个名为{{1}的属性}

但您致电tmpIthis.tmpO.t = 1;的地方并未创建实例的属性,而是直接更改this.tmpA[0] = 1的属性。

全部是因为在定义数组或对象之前无法创建数组或对象成员。为避免这种情况,

__proto__

现在您正在创建和更改实例属性.prototype属性永远不会被更改。

    this.tmpI = "";
    this.tmpO = {};
    this.tmpA = [];
    this.tmpI = 1;
    this.tmpO.t = 1;
    this.tmpA[0] = 1;

ofc删除实例属性后,@ tmpI,tmpO,tmpA再次指向原型属性。

 init::BaseView
(index):46 *** I: 0 O: 0 A: 0
(index):59 *** I: 1 O: 1 A: 1
(index):33 init::BaseView
(index):46 *** I: 0 O: 0 A: 0
(index):59 *** I: 1 O: 1 A: 1