YUI 3.x Home -

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.

Using augment

Instantiate YUI

  1. <!-- include yui -->
  2. <script type="text/javascript" src="../../build/yui/yui.js"></script>
  3.  
  4. YUI().use("node", function(Y) {
  5. // This method is in the 'oop' module. Since we require 'node'
  6. // for this example, and 'node' requires 'oop', the 'oop' module
  7. // 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.

  1. YUI().use("node", function(Y) {
  2. // This method is in the 'oop' module. Since we require 'node'
  3. // for this example, and 'node' requires 'oop', the 'oop' module
  4. // will be loaded automatically.
  5.  
  6. var Foo = function() {
  7. /* code specific to Foo */
  8. this.publish('interestingMoment');
  9. };
  10.  
  11. Foo.prototype.doSomething = function() {
  12.  
  13. var eventData = {};
  14.  
  15. // -- do something interesting, add results to eventData --
  16.  
  17. eventData.statusText = 'bar';
  18.  
  19. // notify the subscribers, passing the event data
  20. this.fire('interestingMoment', eventData);
  21. }
  22.  
  23. Y.augment(Foo, Y.EventTarget);
  24.  
  25. var foo = new Foo();
  26.  
  27. // add some event listeners
  28. foo.on('interestingMoment', function (data) {
  29. var p = Y.one('#demo_p1');
  30. p.set('innerHTML', 'I was notified of an interesting moment: ' + data.statusText);
  31. });
  32.  
  33. foo.on('interestingMoment', function (data) {
  34. var p = Y.one('#demo_p2');
  35. p.set('innerHTML', 'I was also notified of an interesting moment: ' + data.statusText);
  36. });
  37.  
  38. Y.on('click', function() {
  39. foo.doSomething();
  40. }, '#demo');
  41. });
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 extended 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.

Diagram showing class hierarchy, highlighting has-a relationship

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.

  1. YUI().use('oop', function(Y) {
  2.  
  3. function Foo() {}
  4. Foo.prototype.doSomething = function () { /* something */ };
  5.  
  6. function Bar() {}
  7. Y.augment(Bar, Foo);
  8.  
  9. var b = new Bar();
  10. if (b instanceof Bar) {} // true
  11. if (b instanceof Foo) {} // FALSE
  12. });
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 © 2009 Yahoo! Inc. All rights reserved.

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