Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

Layer 1: Single objects

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Layer 2: Prototype chains

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Layer 3: Constructors

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Layer 4: Inheritance between constructors

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Conclusion

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

Bonus

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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