Introducing Underscore

In addition to jQuery, Backbone also requires one library called Underscore. Underscore was written by Jeremy Ashkenas (the creator of Backbone), and many of its functions are relevant to the topics we've discussed so far. Because Underscore is required by Backbone, you'll already have it available to you if you use Backbone. All of these functions can be accessed via the _ character (similar to how jQuery functions are accessed via the $ character).

As we discussed the call and apply methods, you may have realized that this is more fluid in JavaScript than in other languages. While a function that is called normally will preserve the this method automatically, when a function is called in an unusual way—such as through window.setTimeout or as a callback to a jQuery event handler or AJAX call—that won't be the case. The window.setTimeout will change this to the global window object, while jQuery event callbacks will change this to the element that triggered the event and jQuery AJAX callbacks will set it to the HTTP request created by the AJAX call. Here's a quick example:

var exampleObject = {};
exampleObject.alertThis = function() {
     alert(this);
};
window.setTimeout(exampleObject.alertThis); // alerts window

The solution to this problem is to use extra functions and use apply to wrap the original function so that we can force JavaScript to preserve our this method:

      var exampleObject = {};
exampleObject.alertThisBuilder = function() {
    var alertThis = function() {
        alert(this);
    }
    var correctThis = this;
    return function() {
        alertThis.apply(correctThis);
    }
};
var alertThis = exampleObject.alertThisBuilder();
window.setTimeout(alertThis); // alerts exampleObject

This works but let's face it: it's ugly. Luckily, Underscore has a two solution for this: bind and bindAll.

Let's start with bind. The bind functions allows you to force a function, which you provide as the first argument, to preserve a specific this value, which you provide as the second argument:

var simpleBook = {};
simpleBook.alertThis = function() {
     alert(this);
};
simpleBook.alertThis = _.bind(simpleBook.alertThis, simpleBook);
window.setTimeout(simpleBook.alertThis); // now alerts simpleBook, not window

Underscore also has a related bindAll function, which can be used to permanently bind a method:

var Book = Backbone.Model.extend({
     initialize: function() {
          _.bindAll(this, 'alertThis'),
     },
     alertThis: function() {
          alert(this);
     }
});
var  book = new Book();
window.setTimeout(book.alertThis); // alerts book, not window

As you can see, bindAll allows you to use your class's methods with setTimeout or as callbacks to jQuery event handlers or AJAX operations, without losing this.

While bindAll is very powerful, it is important not to overuse it, because it creates a new copy of every method it binds. If used inside a class, this will result in every instance of that class to have its own separate copy of that method. While this is perfectly fine when you only have a few bound methods and/or only a few instances, you will not want to use it on a large number of methods with a class that will be instantiated many times.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.202.174