Javascript 为什么instanceof关键字不适用于主干js模型?
我正在构建一个主干JS应用程序,它涉及到继承和instanceof javascript关键字的使用 我有以下代码:Javascript 为什么instanceof关键字不适用于主干js模型?,javascript,oop,backbone.js,Javascript,Oop,Backbone.js,我正在构建一个主干JS应用程序,它涉及到继承和instanceof javascript关键字的使用 我有以下代码: app.Sport = Backbone.Model.extend ({ defaults: { id: 0, title: 'Running' } }); 在代码中,我通过键入以下内容实例化了一项新运动: var newSport = new app.Sport (); 我可以操纵这个新创建的实例而不会出现问题 但是,
app.Sport = Backbone.Model.extend
({
defaults:
{
id: 0,
title: 'Running'
}
});
在代码中,我通过键入以下内容实例化了一项新运动:
var newSport = new app.Sport ();
我可以操纵这个新创建的实例而不会出现问题
但是,因为有一个But,当询问我的实例类型时,instanceof关键字总是返回false:
console.log ('is newSport a Sport instance ? ' + newSport instanceof app.Sport);
始终显示false。为什么?
注意:在我的问题中我没有提到继承,因为它甚至不适用于简单的OOP形式(基类的一个实例,并在后面询问类型)
我最初的目的是根据运动类型触发特定动作(因此使用instanceof关键字);它可能很酷,也可能是极端的:
app.CoolSport = app.Sport.extend ({ ... });
app.ExtremeSport = app.Sport.extend ({ ... });
编辑:我隔离了问题。它没有链接到instanceof关键字或我声明的模型。相反,我填充了一个主干集合,并推动它进行一些不同类型的运动。以下是测试代码:() 你猜怎么着?我的CoolSport实例。。。不是CoolSport的实例。我怀疑主干SportList集合的init是问题所在 有什么想法吗?请不要这样:
console.log ('is newSport a Sport instance ? ' + newSport instanceof app.Sport);
做对了:
console.log ('is newSport a Sport instance ? ' + (newSport instanceof app.Sport));
或
我找到了解决办法:-)
我在下面对代码进行了注释:
var coolSport1 = new app.CoolSport();
// Of course it is
console.log ('is coolSport1 a Sport instance ? ' , coolSport1 instanceof app.Sport);
console.log ('is coolSport1 a CoolSport instance ? ' , coolSport1 instanceof app.CoolSport);
var sportList = new app.SportList();
// Here is the tricky part : we push the JSON representation of our CoolSport instance
sportList.push (coolSport1.toJSON());
// Backbone does not know anymore the subtype of our instance, as it has been JSON stringified juste before.
sportList.each ( function ( sport )
{
if ( sport instanceof app.CoolSport )
{
console.log ( "sport is an instance of Cool Sport ! Yeah !" , sport instanceof app.CoolSport ) ;
}
else
{
console.log ( "Not a CoolSport instance..");
}
});
主干文档为这种行为提供了一种机制:
var Library = Backbone.Collection.extend({
model: function(attrs, options) {
if (condition) {
return new PublicDocument(attrs, options);
} else {
return new PrivateDocument(attrs, options);
}
}
});
它告诉集合如何处理JSON表示,以便向列表中添加正确的子类型实例。因此,要在保持代码不变的情况下添加CoolSport,只需在SportList集合中添加model函数,并返回一个新的CoolSport(如果它包含“uselessAttr”(请参阅我问题中的代码)
我采用了另一种方式,通过集合的add()方法直接传递了一个CoolSport实例,从而保留了它的子类型
谢谢大家的帮助,希望我的回答能帮助其他人:-)您将收藏中的模型定义为“app.Sport” 因此,在推送coolSport1.toJSON()时,将使用app.Sport model对其进行初始化
这就是为什么它不是一个CoolSport实例,而是一个Sport实例 我似乎很难重现你的问题,但我的测试表明这应该如预期的那样有效。您使用的是哪个版本的主干/下划线?(fiddle:)尝试写下console.log('newSport是运动实例吗?',(newSport instanceof app.Sport));-您将获得instanceof
“newSport是运动实例吗?+新闻端口
-对我来说也是一样的:它正在JSFIDLE上工作。这不是版本问题。请看我最新的问题(问题与收藏有关)。我永远不会用不好的方式去做。谢谢你指出这个错误。请看我的最新问题,因为它说明了我的真实问题。我在你之前几分钟发现了同样的问题(见我的回答,就在下面),这确实是正确的解决方案。如果不是我一个人找到的话,我很高兴你在那里;-)
var coolSport1 = new app.CoolSport();
// Of course it is
console.log ('is coolSport1 a Sport instance ? ' , coolSport1 instanceof app.Sport);
console.log ('is coolSport1 a CoolSport instance ? ' , coolSport1 instanceof app.CoolSport);
var sportList = new app.SportList();
// Here is the tricky part : we push the JSON representation of our CoolSport instance
sportList.push (coolSport1.toJSON());
// Backbone does not know anymore the subtype of our instance, as it has been JSON stringified juste before.
sportList.each ( function ( sport )
{
if ( sport instanceof app.CoolSport )
{
console.log ( "sport is an instance of Cool Sport ! Yeah !" , sport instanceof app.CoolSport ) ;
}
else
{
console.log ( "Not a CoolSport instance..");
}
});
var Library = Backbone.Collection.extend({
model: function(attrs, options) {
if (condition) {
return new PublicDocument(attrs, options);
} else {
return new PrivateDocument(attrs, options);
}
}
});