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

5592487d2231fbe06ed2ac80d92c8f20?s=128

Axel Rauschmayer

February 25, 2014
Tweet

Transcript

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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 <name> (<title>)' Dr. Axel Rauschmayer (2ality.com) The Four Layers of JavaScript OOP 2014-02-25 22 / 35
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 30.
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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