继this question后,我试图用一些自定义方法扩充Backbone.Collection。但是,我在控制台和源之间出现了一些不一致的行为。
以下是测试的外观
HTML
...
<script type="text/javascript" src="./libs/underscore.js"></script>
<script type="text/javascript" src="./libs/backbone.js"></script>
<script type="text/javascript" src="./libs/backbone-extend.js"></script>
<script type="text/javascript" src="./qunit/qunit.js"></script>
<script type="text/javascript" src="./backbone-extend-tests.js"></script>
</body></html>
骨架extend.js
Backbone.Collection.prototype.extract = function() {
// placeholder to test binding
return 'foo';
};
主链延伸-tests.js
test('extending backbone', function () {
ok(typeof Backbone.Collection.extract == 'function');
console.log(Backbone.Collection.extract); // undefined
});
有什么我想念的吗?我检查过所有的源码都在加载
JFTR - 这......
_.extend(Backbone.Collection, {extract:function(){return'foo';});
...有效,只是没有使用原型扩充方法。鉴于Backbone recommend原型扩充的文档(尽管它特别提到了模型),我只是不确定为什么一种方法有效而另一种方法无效。猜猜我需要在发动机罩下更详细一点......
更新 为后代,将其放在backbone-extend.js文件中......
_.extend(Backbone.Collection.prototype, {
extract : function (model) {
var _model = model;
this.remove(model);
return _model;
}
});
......工作
答案 0 :(得分:9)
你正在混淆一些关键概念,这就是为什么你没有看到你期望的行为,这更像是一个基本的javascript问题而且与骨干无关。
考虑以下构造函数:
var Klass = function() {};
您可以使用new
关键字调用该构造函数,以从该构造函数中获取实例。
var klassInstance = new Klass();
现在,假设我想添加一个可用于所有从该构造函数派生的实例的方法。为此,我可以使用prototype
对象。
Klass.prototype.instanceMethod = function() { alert('hi'); };
然后我应该能够使用以下方法调用该方法:
klassInstance.instanceMethod();
但是,我还可以添加一个 static 函数 - 我在这个上下文中使用松散的术语 - 到构造函数本身,可以在没有实例的情况下调用它。
Klass.staticMethod = function() { alert('yo!'); };
此方法将直接在构造函数之外使用,但不可直接从实例中获取。
例如:
klassInstance.staticMethod == undefined
因此,您的测试真正的错误在于您正在向prototype
添加一个方法 - 一种可用于该“类”的所有实例的方法 - 但在您的测试中,您正在测试方法直接在“阶级”本身。这不是一回事。
除此之外,Backbone.js提供了一个内置的机制来创建内置类型的“子类”。这是静态 .extend()
方法。这为您提供了一种将自己的功能添加到基本Backbone类的简单方法。
在您的情况下,您可能希望执行以下操作:
var MyCollection = Backbone.Collection.extend({
extract: function() {
// do whatever
}
})
然后,您可以创建新类的实例,它们将使用.extract()
方法:
var coll = new MyCollection();
coll.extract();
最终 - 回到原来的问题 - 如果您想要一个可在特定类的所有实例上使用的方法,那么您的测试是不正确的。您需要新建一个实例来测试:
test('extending backbone', function () {
var col = new Backbone.Collection();
ok(typeof col.extract == 'function');
});
或直接检查prototype
方法 - 这与prototype
对象不是仅对象获取方法的事实截然不同。
test('extending backbone', function () {
ok(typeof Backbone.Collection.prototype.extract == 'function');
});
答案 1 :(得分:0)
确保backbone.js
和underscore.js
在完成测试之前已完全加载。