Totally agree with this post - I was a 'JavaScript =~ jQuery' guy before I picked up Backbone - writing hopelessly average jQuery spaghetti (with the best of intentions - I'm a designer and had never looked at JS as a programming language.
Backbone has totally changed all of that - learnt so much about design patterns in such a short space of time - shout out to Addy Osmani for writing such down-to-earth, approachable content.
I also agree, although instead of Backbone I recently found that Twitter Bootstrap's javascript files offer similar insights as to how to structure code in an javascript-style object oriented manner. For example: https://github.com/twitter/bootstrap/blob/master/js/bootstra...
Aside from the always controversy-inducing lack of semicolons and the slightly unintuitive leading bang for the IIFE, I don't really see what's wrong with this code.
Something doesn't have to be wrong to be bad learning material. That code is chock full of unconventional js. For example, why they declare their objects like this:
var Typeahead = ...
Typeahead.prototype = {
constructor: Typeahead
...
rather than the usual
function Typeahead() { ...
Typeahead.prototype = { ...
I'm not sure why they are prefixing the initial plugin with a `!`, but if it's the same as using a `(` then would the reason they are using `var Typeahead = ...` is to keep that method scoped to just this plugin and not global as `function Typeahead` would be doing?
I'm kind of ignorant at the moment of proper best practices of js, but eager to learn more, so if you could explain to me why one is better than the other, that'd be rad :)
No, the ! is to turn the function into an expression, and thus guarantee that it is executed. It is meant to protect against concatenating with JavaScript that is missing a semi-colon at the end of its file. This is extreme minutiae and why I said you shouldn't use that code to learn.
It turns -1 (indexOf's "not found" result) into 0 (i.e. something falsy). Any other value is turned into something which isn't 0 (i.e. something truthy).
indexOf returns -1 if the query isn't found in the string; -1 is usually represented as all bits 1, so a bitwise not on -1 is 0, which when converted to a Boolean is false. So ~x is more-or-less equivalent to x != -1; but its a bit obscure, and seems like bad style to me (indeed, I'm not even sure if the ECMAScript standard guarantees that -1 is stored as all bits 1, so it may not even by correct).
Numbers are IEEE 754 floating point. It's a separate standard which they just had to reference.
I do agree that it's bad style, because it doesn't clearly communicate the intention. If you want something that returns true or false, you should return true or false.
Yeah, but -1 isn't represented in IEEE 754 floating point as all bits one, is it? The ECMAScript standard specifies that the bitwise operators work by first converting their arguments to 32-bit signed integers, but at least how I read it, it doesn't actually say anything about how these 32-bit signed integers are represented (which implies that they continue to be represented as IEEE 754, which isn't how browsers behave, and wouldn't be very useful).
It's not. And you're right, the spec isn't clear. On the other hand, the current behavior of pretending the bits are arranged in 32-bit two's-complement fashion for appropriate integer values when applying bitwise operators is really the only sensible interpretation (especially since a 64-bit float can represent all 32-bit ints).
Backbone has totally changed all of that - learnt so much about design patterns in such a short space of time - shout out to Addy Osmani for writing such down-to-earth, approachable content.