Applying parent methods

In order to realize the full power of a class system, however, it's not enough to just define new methods on subclasses; sometimes, we need to combine a method of a parent class with additional logic on a subclass. In traditional object-oriented languages, this is often done by referencing a special super object; but in JavaScript, no such object exists, which means that we have to utilize JavaScript's apply or call methods instead.

For instance, Backbone.Model has a destroy method, but what if we want our Book class to also have its own destroy method? This method might take a number of pages and destroy them (reduce the total number of pages by that amount), but at the same time, we might want to keep the Backbone version around for its original purpose (which is to destroy the server-side version of the Book).

Luckily, because Backbone properly configured our Book class's prototype for us, calling the parent method from the subclass method is fairly straightforward, as shown here:

var Book = Backbone.Model.extend({
    destroy: function(optionsOrPagesToDestroy) {
        if (typeof optionsOrPagesToDestroy === 'number') {
            // optionsOrPagesToDestroy is pagesToDestroy: call our version
            this.totalPages -=  optionsOrPagesToDestroy;
        } else {
            // optionsOrPagesToDestroy is an options object: call the Backbone version
            Backbone.Model.prototype.destroy.apply(this, arguments);
        }
    }
});

The key to making the preceding code work is the apply method, which is a method of every function in JavaScript (since functions are also objects in JavaScript, it is possible for them to have methods just like any other object). The apply method allows you to call its function as if it were called from the first argument given to apply. In other words, apply allows you to change a function's this method when it is invoked.

As mentioned before, under normal conditions, this will be set to the object from which the function was called. However, when you use apply, you can instead change this to whatever variable you want, as follows:

var Book = Backbone.Model.extend({
    currentPage: 1,
    turnPage: function() {
        this.currentPage += 1;
    }
});
var simpleBook = {currentPage: 20};
Book.prototype.turnPage.apply(simpleBook); //  simpleBook.currentPage == 21

You can also pass regular arguments to a method using apply, by providing them as a second (array) argument. In fact, apply can be used even if this isn't relevant to the function you're trying to call, and in that case, you can simply pass null as the first argument:

var Book = Backbone.Model.extend();
var book = new Book();
book.alertMessage = function(message, secondMessage) {
    alert(message + ' ' + secondMessage);
}
book.alertMessage.apply(null, ['hello', 'world']);// alerts "hello world"

JavaScript functions also have a similar method: call. The difference between call and apply is how they provide arguments to the function they invoke. Unlike apply, call expects its arguments to be passed in separately, rather than as a single array argument. Take an example of the following code snippet:

var book = new Book();
book.alertMessage = function(message, secondMessage) {
    alert(message + ' ' + secondMessage);
}
book.alertMessage.call(null, 'hello', 'world'), // alerts "hello world"

By using one of these two methods and remembering that every method of a class is available to you on its prototype property, you can call not just the methods of a parent class but also the methods of a grandparent, great grandparent, or even a completely unrelated class. For readability reasons, you shouldn't utilize this technique too often on unrelated classes, but occasionally it can be quite helpful.

Note

It's also worth noting that this technique is only possible in a prototype-based inheritance language such as JavaScript; it will be impossible to implement apply or call in a true object-oriented language such as Java.

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

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