YUI 3.x Home -

Site Search (YDN & YUIBlog):

# YUI Library Examples: The YUI Global Object: Compose Classes of Objects with `augment`

## The YUI Global Object: Compose Classes of Objects with `augment`

In this example, a class has been created then augmented with `EventTarget` to provide custom event functionality.

Click the Send button to send the instance of the new class a request.

View example in new window.

## Using `augment`

### Instantiate YUI

    <!-- include yui --><script type="text/javascript" src="../../build/yui/yui.js"></script> YUI().use("node", function(Y) {    // This method is in the 'oop' module.  Since we require 'node'    // for this example, and 'node' requires 'oop', the 'oop' module    // will be loaded automatically.

    <!-- include yui -->
    <script type="text/javascript" src="../../build/yui/yui.js"></script>

    YUI().use("node", function(Y) {
        // This method is in the 'oop' module.  Since we require 'node'
        // for this example, and 'node' requires 'oop', the 'oop' module
        // will be loaded automatically.

<!-- include yui --> <script type="text/javascript" src="../../build/yui/yui.js"></script> YUI().use("node", function(Y) { // This method is in the 'oop' module. Since we require 'node' // for this example, and 'node' requires 'oop', the 'oop' module // will be loaded automatically.

### The example: Any class can be an `EventTarget`

This example creates a custom class, then augments it with `EventTarget` (functionality included in the YUI Event Utility). Using the packaged functionality of `EventTarget`, the code for `Foo` is able to focus on the functionality unique to its purpose.

    YUI().use("node", function(Y) {    // This method is in the 'oop' module.  Since we require 'node'    // for this example, and 'node' requires 'oop', the 'oop' module    // will be loaded automatically.     var Foo = function() {        /* code specific to Foo */        this.publish('interestingMoment');    };     Foo.prototype.doSomething = function() {         var eventData = {};         // -- do something interesting, add results to eventData --         eventData.statusText = 'bar';         // notify the subscribers, passing the event data        this.fire('interestingMoment', eventData);    }     Y.augment(Foo, Y.EventTarget);     var foo = new Foo();     // add some event listeners    foo.on('interestingMoment', function (data) {        var p = Y.one('#demo_p1');        p.set('innerHTML', 'I was notified of an interesting moment: ' + data.statusText);    });     foo.on('interestingMoment', function (data) {        var p = Y.one('#demo_p2');        p.set('innerHTML', 'I was also notified of an interesting moment: ' + data.statusText);    });     Y.on('click', function() {         foo.doSomething();    }, '#demo');});

    YUI().use("node", function(Y) {
        // This method is in the 'oop' module.  Since we require 'node'
        // for this example, and 'node' requires 'oop', the 'oop' module
        // will be loaded automatically.

        var Foo = function() {
            /* code specific to Foo */
            this.publish('interestingMoment');
        };

        Foo.prototype.doSomething = function() {

            var eventData = {};

            // -- do something interesting, add results to eventData --

            eventData.statusText = 'bar';

            // notify the subscribers, passing the event data
            this.fire('interestingMoment', eventData);
        }

        Y.augment(Foo, Y.EventTarget);

        var foo = new Foo();

        // add some event listeners
        foo.on('interestingMoment', function (data) {
            var p = Y.one('#demo_p1');
            p.set('innerHTML', 'I was notified of an interesting moment: ' + data.statusText);
        });

        foo.on('interestingMoment', function (data) {
            var p = Y.one('#demo_p2');
            p.set('innerHTML', 'I was also notified of an interesting moment: ' + data.statusText);
        });

        Y.on('click', function() {
            foo.doSomething();
        }, '#demo');
    });

YUI().use("node", function(Y) { // This method is in the 'oop' module. Since we require 'node' // for this example, and 'node' requires 'oop', the 'oop' module // will be loaded automatically. var Foo = function() { /* code specific to Foo */ this.publish('interestingMoment'); }; Foo.prototype.doSomething = function() { var eventData = {}; // -- do something interesting, add results to eventData -- eventData.statusText = 'bar'; // notify the subscribers, passing the event data this.fire('interestingMoment', eventData); } Y.augment(Foo, Y.EventTarget); var foo = new Foo(); // add some event listeners foo.on('interestingMoment', function (data) { var p = Y.one('#demo_p1'); p.set('innerHTML', 'I was notified of an interesting moment: ' + data.statusText); }); foo.on('interestingMoment', function (data) { var p = Y.one('#demo_p2'); p.set('innerHTML', 'I was also notified of an interesting moment: ' + data.statusText); }); Y.on('click', function() { foo.doSomething(); }, '#demo'); });

### Composition, not inheritance

If `Foo` were a part of a class hierarchy, it would be improper to include `EventTarget` in the inheritance chain, because its custom event functionality is not an intrinsic characteristic but rather an ancillary, generic capability that many classes share.

Unlike `extend`ed classes, the relationship between a class and the classes augmenting it is not an indication of type hierarchy. The intent of `augment` is to aid in extracting nonessential behaviors or behaviors shared by many classes, allowing for a composition-style class architecture.

This may appear similar to multiple inheritance, but it's not. `augment` simply adds the public methods and members from one class prototype to another class prototype. Instances of the augmented class will not pass `instanceof` tests for the class(es) which augmented it.

    YUI().use('oop', function(Y) {     function Foo() {}    Foo.prototype.doSomething = function () { /* something */ };     function Bar() {}    Y.augment(Bar, Foo);     var b = new Bar();    if (b instanceof Bar) {} // true     if (b instanceof Foo) {} // FALSE});

    YUI().use('oop', function(Y) {

        function Foo() {}
        Foo.prototype.doSomething = function () { /* something */ };

        function Bar() {}
        Y.augment(Bar, Foo);

        var b = new Bar();
        if (b instanceof Bar) {} // true
        if (b instanceof Foo) {} // FALSE
    });

YUI().use('oop', function(Y) { function Foo() {} Foo.prototype.doSomething = function () { /* something */ }; function Bar() {} Y.augment(Bar, Foo); var b = new Bar(); if (b instanceof Bar) {} // true if (b instanceof Foo) {} // FALSE });

Copyright © 2010 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings