Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Four Layers of JavaScript OOP

The Four Layers of JavaScript OOP

Watch the talk:
– Just the video: http://youtu.be/VJOTcUsD2kA?t=6m14s (start watching at 6m14s!)
– Webcast (including text of chat): http://www.oreillynet.com/pub/e/3008

Axel Rauschmayer

February 25, 2014
Tweet

More Decks by Axel Rauschmayer

Other Decks in Programming

Transcript

  1. The Four Layers of JavaScript OOP
    Dr. Axel Rauschmayer
    2ality.com
    2014-02-25
    Webcast

    View Slide

  2. Level of JavaScript knowledge?
    Understanding OOP (any language)
    Single objects (object literals)
    Constructors
    Prototype chains
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 2 / 35

    View Slide

  3. The four layers
    How to best learn JavaScript OOP?
    Object
    Prototype
    Constructor
    new

    Object
    Layer 1:
    single
    object
    Layer 2:
    prototype
    chain
    Layer 3:
    constructor
    SubConstr
    SuperConstr
    Layer 4:
    constructor
    inheritance
    __proto__
    __proto__
    Instance
    Prototype

    __proto__
    __proto__
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 3 / 35

    View Slide

  4. Layer 1: Single objects

    View Slide

  5. Layer 1: Single objects
    Creating a single object
    Objects: atomic building blocks of JavaScript OOP.
    Objects: maps from strings to values
    Properties: entries in the map
    Methods: properties whose values are functions
    this refers to receiver of method call
    // Object literal
    var jane = {
    // Property
    name: 'Jane',
    // Method
    describe: function () {
    return 'Person named ' + this.name;
    }
    };
    JS advantage: create objects directly, introduce abstractions later
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 5 / 35

    View Slide

  6. Layer 1: Single objects
    var jane = {
    name: 'Jane',
    describe: function () {
    return 'Person named ' + this.name;
    }
    };
    # jane.name
    'Jane'
    # jane.describe
    [Function]
    # jane.describe()
    'Person named Jane'
    # jane.name = 'John';
    # jane.describe()
    'Person named John'
    # jane.unknownProperty
    undefined
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 6 / 35

    View Slide

  7. Layer 1: Single objects
    Objects versus maps
    Similar:
    Very dynamic: freely delete and add properties
    Different:
    inheritance (via prototype chains)
    fast access to properties (via constructors1)
    1If you don’t add or remove properties after construction.
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 7 / 35

    View Slide

  8. Layer 2: Prototype chains

    View Slide

  9. Layer 2: Prototype chains
    Sharing properties: the problem
    var jane = {
    name: 'Jane',
    describe: function () {
    return 'Person named ' + this.name;
    }
    };
    var tarzan = {
    name: 'Tarzan',
    describe: function () {
    return 'Person named ' + this.name;
    }
    };
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 9 / 35

    View Slide

  10. Layer 2: Prototype chains
    Sharing properties: the solution
    __proto__
    name 'Jane' name
    __proto__
    'Tarzan'
    describe function() {...}
    jane tarzan
    PersonProto
    jane and tarzan share the same prototype object.
    Both prototype chains work like single objects.
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 10 / 35

    View Slide

  11. Layer 2: Prototype chains
    Sharing properties: the code
    var PersonProto = {
    describe: function () {
    return 'Person named ' + this.name;
    }
    };
    var jane = {
    __proto__: PersonProto,
    name: 'Jane'
    };
    var tarzan = {
    __proto__: PersonProto,
    name: 'Tarzan'
    };
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 11 / 35

    View Slide

  12. Layer 2: Prototype chains
    Getting and setting the prototype
    ECMAScript 6: __proto__
    ECMAScript 5:
    Object.create()
    Object.getPrototypeOf()
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 12 / 35

    View Slide

  13. Layer 2: Prototype chains
    Getting and setting the prototype
    Object.create(proto)
    var PersonProto = {
    describe: function () {
    return 'Person named ' + this.name;
    }
    };
    var jane = Object.create(PersonProto);
    jane.name = 'Jane';
    Object.getPrototypeOf(obj)
    # Object.getPrototypeOf(jane) === PersonProto
    true
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 13 / 35

    View Slide

  14. Layer 3: Constructors

    View Slide

  15. Layer 3: Constructors
    A constructor for persons
    function Person(name) {
    this.name = name;
    this.describe = function () {
    return 'Person named ' + this.name;
    };
    }
    var jane = new Person('Jane');
    console.log(jane instanceof Person); // true
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 15 / 35

    View Slide

  16. Layer 3: Constructors
    Instances created by the constructor
    describe function() {...}
    name 'Tarzan'
    tarzan
    describe function() {...}
    name 'Jane'
    jane
    How to eliminate the redundancy?
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 16 / 35

    View Slide

  17. Layer 3: Constructors
    Sharing methods
    // Instance-specific properties
    function Person(name) {
    this.name = name;
    }
    // Shared properties
    Person.prototype.describe = function () {
    return 'Person named ' + this.name;
    };
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 17 / 35

    View Slide

  18. Layer 3: Constructors
    Instances created by the constructor
    __proto__
    name 'Tarzan'
    describe function() {...}
    tarzan
    Person.prototype
    prototype
    Person
    function Person(name) {
    this.name = name;
    }
    __proto__
    name 'Jane'
    jane
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 18 / 35

    View Slide

  19. Layer 3: Constructors
    Two prototypes
    Overloaded terminology:
    Prototype 1: prototype relationship between objects
    Prototype 2: property prototype of constructors
    (the prototype of all instances)
    Disambiguation (if necessary): call prototype 2 the instance prototype.
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 19 / 35

    View Slide

  20. Layer 3: Constructors
    instanceof
    Is value an instance of Constr?
    value instanceof Constr
    How does instanceof work?
    Check: Is Constr.prototype in the prototype chain of value?
    // Equivalent
    value instanceof Constr
    Constr.prototype.isPrototypeOf(value)
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 20 / 35

    View Slide

  21. Layer 4: Inheritance between constructors

    View Slide

  22. Layer 4: Inheritance between constructors
    Goal: derive Employee from Person
    function Person(name) {
    this.name = name;
    }
    Person.prototype.sayHelloTo = function (otherName) {
    console.log(this.name + ' says hello to ' + otherName);
    };
    Person.prototype.describe = function () {
    return 'Person named ' + this.name;
    };
    Employee(name, title) is like Person, except:
    Additional instance property: title
    describe() returns 'Person named ()'
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 22 / 35

    View Slide

  23. Layer 4: Inheritance between constructors
    Things we need to do
    Employee must
    Inherit Person’s instance properties
    Create the instance property title
    Inherit Person’s prototype properties
    Override method Person.prototype.describe
    (and call overridden method)
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 23 / 35

    View Slide

  24. Layer 4: Inheritance between constructors
    Employee: the code
    function Employee(name, title) {
    Person.call(this, name); // (1)
    this.title = title; (2)
    }
    Employee.prototype = Object.create(Person.prototype); // (3)
    Employee.prototype.describe = function () { // (4)
    return Person.prototype.describe.call(this) // (5)
    + ' (' + this.title + ')';
    };
    1 Inherit instance properties
    2 Create the instance property title
    3 Inherit prototype properties
    4 Override method Person.prototype.describe
    5 Call overridden method (a super-call)
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 24 / 35

    View Slide

  25. Layer 4: Inheritance between constructors
    The structure of the constructors
    title 'CTO'
    __proto__
    name 'Jane'
    __proto__
    describe function() {...}
    sayHelloTo function() {...}
    jane
    Person.prototype
    prototype
    Person
    __proto__
    describe function() {...}
    Employee.prototype
    prototype
    Employee
    Object.prototype
    calls
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 25 / 35

    View Slide

  26. Layer 4: Inheritance between constructors
    Built-in constructor hierarchy
    2
    length
    1 'bar'
    __proto__
    0 'foo'

    toString function() {...}
    __proto__ null
    [ 'foo', 'bar' ]
    Object.prototype
    prototype
    Object

    sort function() {...}
    __proto__
    toString function() {...}
    Array.prototype
    prototype
    Array
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 26 / 35

    View Slide

  27. Conclusion

    View Slide

  28. Conclusion
    Summary: the layers
    1 Basic building blocks: objects
    2 Sharing properties: prototype chains
    3 Constructors set up instances. Separation of concerns:
    Instance data: set up by function Constr
    Methods: in Constr.prototype
    4 Inheritance between constructors. Derive Sub from Super:
    Instance data: Sub calls Super (as a function)
    Methods: Sub.prototype has prototype Super.prototype
    Future (ECMAScript 6): classes2 (help especially with layer 4)
    2www.2ality.com/2012/07/esnext-classes.html
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 28 / 35

    View Slide

  29. Thanks!
    Book: “Speaking JavaScript”
    Available in March
    SpeakingJS.com
    Free online
    (subscribe to be notified)

    View Slide

  30. Bonus

    View Slide

  31. Bonus
    Extracting methods
    var counter = {
    count: 0,
    inc: function () {
    this.count++;
    }
    };
    # setTimeout(counter.inc, 0)
    # counter.count
    0
    # setTimeout(counter.inc.bind(counter), 0)
    # counter.count
    1
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 31 / 35

    View Slide

  32. Bonus
    Shadowing this
    var obj = {
    name: 'Jane',
    friends: [ 'Tarzan', 'Cheeta' ],
    loop: function () {
    'use strict';
    this.friends.forEach(
    function (friend) {
    console.log(this.name + ' knows ' + friend);
    }
    );
    }
    };
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 32 / 35

    View Slide

  33. Bonus
    Fix 1: that = this
    loop: function () {
    'use strict';
    var that = this;
    this.friends.forEach(function (friend) {
    console.log(that.name + ' knows ' + friend);
    });
    }
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 33 / 35

    View Slide

  34. Bonus
    Fix 2: bind()
    loop: function () {
    'use strict';
    this.friends.forEach(function (friend) {
    console.log(this.name + ' knows ' + friend);
    }.bind(this));
    }
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 34 / 35

    View Slide

  35. Bonus
    Fix 3: forEach parameter thisValue
    loop: function () {
    'use strict';
    this.friends.forEach(function (friend) {
    console.log(this.name + ' knows ' + friend);
    }, this);
    }
    Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 35 / 35

    View Slide