Why does instanceof keyword not work with Backbone js models?

I am creating a BackBone JS application that includes inheriting and using instanceof javascript keyword.

I have the following code:

app.Sport = Backbone.Model.extend ({ defaults: { id: 0, title: 'Running' } }); 

Further in the code I create a new Sport by typing:

 var newSport = new app.Sport (); 

I can manipulate this newly created instance without problems.

But, as there is, but the instanceof keyword always returns false when prompted for the type of my instance:

 console.log ('is newSport a Sport instance ? ' + newSport instanceof app.Sport); 

false is always displayed. Why?

Note. I did not mention the inheritance in my question, since it does not even work with a simple OOP form (one instance of a base class and a type request right away).

My initial goal is to initiate a specific action depending on the type of sport (thus using the instanceof keyword); It can be cool or extreme:

 app.CoolSport = app.Sport.extend ({ ... }); app.ExtremeSport = app.Sport.extend ({ ... }); 

EDIT . I highlighted the problem. It is not associated with an instanceof keyword or a declared model. Rather, I fill out the Backbone collection and push various sports to it. Here is the test code: ( Fiddle )

 var app = {}; app.Sport = Backbone.Model.extend ({ defaults: { id: 0, title: 'Running' } }); app.CoolSport = app.Sport.extend ({ defaults: { uselessAttr:'I am a Cool Sport !' } }); app.SportList = Backbone.Collection.extend ({ model: app.Sport }); var coolSport1 = new app.CoolSport(); console.log ('is coolSport1 a Sport instance ? ' , coolSport1 instanceof app.Sport); console.log ('is coolSport1 a CoolSport instance ? ' , coolSport1 instanceof app.CoolSport); console.log ('is coolSport1 a CoolSport instance (wrong operand in console) ? ' + coolSport1 instanceof app.CoolSport); var sportList = new app.SportList(); sportList.push (coolSport1.toJSON()); 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.."); } }); 

And guess what? my CoolSport instance ... is not a CoolSport instance. I suspect a build issue of the Backbone SportList is a problem.

Any ideas?

+6
source share
3 answers

I found a solution :-)

I commented on the code below:

 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.."); } }); 

Basic documentation provides a mechanism for this behavior:

 var Library = Backbone.Collection.extend({ model: function(attrs, options) { if (condition) { return new PublicDocument(attrs, options); } else { return new PrivateDocument(attrs, options); } } }); 

It tells the assembly how to handle the JSON representation to add the correct list of subtypes to the list. Thus, to add CoolSport without saving the code without changes, you just need to add the model function to the SportList collection and return a new CoolSport if it contains "uselessAttr" (see the code in my question).

I acted differently and directly passed the CoolSport instance using the add () method of the collection, while retaining its subtype.

Thanks to everyone for their help, and I hope that my answer will help others :-)

+2
source

Please, do not do that:

 console.log ('is newSport a Sport instance ? ' + newSport instanceof app.Sport); 

Do it right:

 console.log ('is newSport a Sport instance ? ' + (newSport instanceof app.Sport)); 

or

 console.log ('is newSport a Sport instance ? ', newSport instanceof app.Sport); 
+5
source

You define the model in your collection as "app.Sport"

so when you click coolSport1.toJSON (), it will be initialized using the app.Sport model

why this is not an instance of CoolSport, but only an instance of Sport.

+1
source

Source: https://habr.com/ru/post/952185/


All Articles