javascript - 为什么 Backbone.View 对象仍然保留在内存中?

标签 javascript backbone.js underscore.js javascript-framework

我有显示对话框的简单 View 。

Backbone.View.prototype.completeRemove = function(){
    this.undelegateEvents();
    this.remove();
    delete this.$el;
    delete this.el;
    console.log('completely removed')
}

MdApp.dialogBox = Backbone.View.extend({

    defaults: {
        text: __('No text provided'),
        buttonText: __('Ok'),
        callback: function(){
            return null;
        },
        el: $('#app-panel'),
        type: 'error',
        cancellable: false,
        cancelText: __('No'),
        picture: pic('default')
    },

    el: '<div class="dialog-box">',

    template: _.template($('#dialog-box-template').html()),

    events: {
        'click .confirm' : 'confirm',
        'click .cancel' : 'cancel'
    },

    initialize: function(){
        this.model = _.extend(this.defaults, this.model);
        this.render();
    },

    render: function(){
        var model = this.model;
        this.$el.html(this.template(model));
        model.el.append(this.el);
    },

    confirm: function(){
        var model = this.model;
        var view = this;
        this.completeRemove();
        model.callback();
    },

    cancel: function(){
        this.completeRemove();
    }
});

它有自己的默认值。每次我初始化新对话框时,它的值都会在每次对话框调用之间保持不变。例如,当我第一次调用对话框时:

new MdApp.dialogBox({model:{
        text: __('Do you really wanna delete this?'),
        buttonText: __('Unfortunately yes'),
        callback: function(){
            //some callback
        },
        cancellable: true,
        cancelText: __('No'),
        picture: pic('confirm delete')
    }});

之后,我调用另一个没有 cancellable 属性的对话框,因此它应该使用默认属性(false),但它保持 true。这适用于所有其他属性(property)。为什么会出现这种情况?

最佳答案

来自fine manual :

extend _.extend(destination, *sources)

Copy all of the properties in the source objects over to the destination object, and return the destination object.

这意味着_.extend(o, ...)修改o 。所以当你这样做时:

this.model = _.extend(this.defaults, this.model);

您正在有效地执行此操作:

for(k in this.model)
    this.defaults[k] = this.model[k];
this.model = this.defaults;

defaults附加到原型(prototype)上,因此实际上您正在更改 defaults这将由 MdApp.dialogBox 的每个实例共享。这就是为什么你最终会得到粘性属性:你正在合并所有不同的 this.model进入defaults在 View 的原型(prototype)上。

你可以这样做:

// Merge into an empty object to avoid altering this.defaults
this.model = _.extend({}, this.defaults, this.model);

或者您可以使用 _.defaults 而不是_.extend :

defaults _.defaults(object, *defaults)

Fill in null and undefined properties in object with values from the defaults objects, and return the object. As soon as the property is filled, further defaults will have no effect.

所以你可以这样做:

_(this.model).defaults(this.defaults);

这将改变this.model就地,因此您的 View 会假设它完全拥有 this.model并且没有任何外部引用该对象。

关于javascript - 为什么 Backbone.View 对象仍然保留在内存中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16594247/

相关文章:

javascript - 如何将 JSF 托管 bean 属性传递给 JavaScript 函数?

javascript - 有没有在 node.js 中做实时模型的框架?

javascript - 按自定义顺序对对象数组进行排序

javascript - 如何搜索两个数组并查找是否匹配?

javascript - 空间不够时如何让div自下而上展开

javascript - 在 JavaScript 中递增 ISO 日期字符串(例如 '2014-03-30' -> '2014-03-31' )

javascript - 可以使用 Backbone 模型的 cid 作为 html id 属性吗?它保证是唯一的吗?

javascript - 在javascript中删除给定字符串的第一个字符的最佳方法

JavaScript 对象文字符号与普通函数和性能影响?

android - Twitter Bootstrap - 构建移动网络应用程序是否足够?