Slide 1

Slide 1 text

Learning to fly Twitter Flight and Mixins @angustweets Thursday, August 22, 13

Slide 2

Slide 2 text

the most difficult part of JS inheritance... And on the 6th day, God created an abundance of Talking Animals, that they may be used in JavaScript inheritance examples. Thursday, August 22, 13

Slide 3

Slide 3 text

So, talking animals it is! meow!! Thursday, August 22, 13

Slide 4

Slide 4 text

Flight flightjs.github.io An event driven web framework by Twitter Thursday, August 22, 13

Slide 5

Slide 5 text

Flight powers... twitter.com tweetdeck gumroad yinzcam crashalytics and more... Thursday, August 22, 13

Slide 6

Slide 6 text

A set of components which bind functionality to DOM Nodes... Thursday, August 22, 13

Slide 7

Slide 7 text

github.com/flightjs/example-app Thursday, August 22, 13

Slide 8

Slide 8 text

github.com/flightjs/example-app Thursday, August 22, 13

Slide 9

Slide 9 text

Components are completely decoupled and communicate via event bubbling Thursday, August 22, 13

Slide 10

Slide 10 text

Thursday, August 22, 13

Slide 11

Slide 11 text

Components often share behaviours Thursday, August 22, 13

Slide 12

Slide 12 text

Components often share behaviours So we needed a re-use technique Thursday, August 22, 13

Slide 13

Slide 13 text

Inheritance classical composition mixins Functions Object.create Constructor.prototype function passing / callbacks Objects call/apply functional mixins (Some) JavaScript Re-use Patterns Thursday, August 22, 13

Slide 14

Slide 14 text

Inheritance classical composition mixins Functions Object.create Constructor.prototype function passing / callbacks Objects call/apply functional mixins (Some) JavaScript Re-use Patterns Thursday, August 22, 13

Slide 15

Slide 15 text

Classical Inheritance Thursday, August 22, 13

Slide 16

Slide 16 text

ES 6 is giving us class. Some libraries have their own versions. Thursday, August 22, 13

Slide 17

Slide 17 text

implementation varies widely and abstraction is often leaky (const, static) class, extend and super are reserved words in particular, the relationship between this and super is difficult... Thursday, August 22, 13

Slide 18

Slide 18 text

//Prototype.js var SwimmingAnimal = Class.create(Animal, { type: 'SwimmingAnimal', speak: function($super) { return $super() + ", glug"; } }); //https://github.com/ded/klass var Alien = SuperHuman.extend({ speak: function() { this.supr(); //speak like a SuperHuman } }); Thursday, August 22, 13

Slide 19

Slide 19 text

Do you even want classes? Thursday, August 22, 13

Slide 20

Slide 20 text

Animal Walking Animal Swimming Animal Flying Animal Cat Elephant Crocodile Whale Eagle Bat Egg-laying Animal Migrating Animal Thursday, August 22, 13

Slide 21

Slide 21 text

Crocodile Animal Walking Animal Swimming Animal Flying Animal Cat Elephant Whale Eagle Bat Egg-laying Animal Migrating Animal Thursday, August 22, 13

Slide 22

Slide 22 text

Crocodile Animal Walking Animal Swimming Animal Flying Animal Cat Elephant Whale Eagle Bat Egg-laying Animal Migrating Animal WTF? I walk too!! Thursday, August 22, 13

Slide 23

Slide 23 text

Animal Walking Animal Swimming Animal Flying Animal Cat Elephant Crocodile Whale Eagle Bat Egg-laying Animal Migrating Animal Thursday, August 22, 13

Slide 24

Slide 24 text

Duck? Animal Walking Animal Swimming Animal Flying Animal Cat Elephant Crocodile Whale Eagle Bat Egg-laying Animal Migrating Animal Thursday, August 22, 13

Slide 25

Slide 25 text

Duck? Animal Cat Elephant Crocodile Whale Eagle Bat Thursday, August 22, 13

Slide 26

Slide 26 text

Duck? Animal Cat Elephant Crocodile Whale Eagle Bat Walking Animal Swimming Animal Flying Animal Egg-laying Animal Migrating Animal Thursday, August 22, 13

Slide 27

Slide 27 text

Classical inheritance Requires up-front knowledge of general case Single rooted hierarchy We’re really bad at classification Thursday, August 22, 13

Slide 28

Slide 28 text

Constructor.prototype chaining Thursday, August 22, 13

Slide 29

Slide 29 text

awkward and unnatural Thursday, August 22, 13

Slide 30

Slide 30 text

var Animal = function(gender, says) { this.gender = gender; this.says = says; }; var WalkingAnimal = function(gender, says) { Animal.call(this, gender, says); } WalkingAnimal.prototype = new Animal(); Thursday, August 22, 13

Slide 31

Slide 31 text

...and new Constructor syntax is classical inheritance Thursday, August 22, 13

Slide 32

Slide 32 text

Beyond classification... Thursday, August 22, 13

Slide 33

Slide 33 text

19th century British philosophers Whewell and Jevons argued that there are no objectively “right” classifications Thursday, August 22, 13

Slide 34

Slide 34 text

“In general, when working with prototypes, one typically chooses not to categorize but to exploit alikeness.” –Antero Taivalsaari (Nokia Research Center) Thursday, August 22, 13

Slide 35

Slide 35 text

liberates prototype chaining from classification Object.create Thursday, August 22, 13

Slide 36

Slide 36 text

var animalProto = { speak: function() { console.log(this.says); } } var walkingAnimalProto = Object.create(animalProto); // then augment walkingAnimalProto here... Thursday, August 22, 13

Slide 37

Slide 37 text

but, that second argument :’’( Thursday, August 22, 13

Slide 38

Slide 38 text

var animalProto = { speak: function() { console.log(this.says); } } var walkingAnimalProto = Object.create( animalProto, { walk: { value: function() { console.log('walking'); } } //... } ); Thursday, August 22, 13

Slide 39

Slide 39 text

and inheritance is still single rooted Thursday, August 22, 13

Slide 40

Slide 40 text

The sad thing is that we even care about inheritance hierarchies... Thursday, August 22, 13

Slide 41

Slide 41 text

The sad thing is that we even care about inheritance hierarchies... ...because in JavaScript they’re quite unnecessary... Thursday, August 22, 13

Slide 42

Slide 42 text

JavaScript has first class functions Any function can be assigned to any object Thursday, August 22, 13

Slide 43

Slide 43 text

Mixins Thursday, August 22, 13

Slide 44

Slide 44 text

//A property copy mixin var withWalking = { walk: function() { console.log('walking'); }, turn: function(direction) { console.log('turning', direction); }, stopWalking: function() { console.log('stopped walking'); } }; Thursday, August 22, 13

Slide 45

Slide 45 text

var extend = function(destination, source) { for (var k in source) { if (source.hasOwnProperty(k)) { destination[k] = source[k]; } } return destination; }; extend(Crocodile.prototype, withWalking); extend(Crocodile.prototype, withSwimming); Thursday, August 22, 13

Slide 46

Slide 46 text

No hierarchical constraints Functionality is grouped by what it does not who it belongs to Define special cases first; common code later Thursday, August 22, 13

Slide 47

Slide 47 text

Mixin must know about target Properties can only clobber But... Thursday, August 22, 13

Slide 48

Slide 48 text

Functional Mixins Thursday, August 22, 13

Slide 49

Slide 49 text

var withWalking = function() { this.walk = function() { console.log('walking'); }; this.turn = function(direction) { console.log('turning', direction); }; this.stopWalking = function() { console.log('stopped walking'); }; }; Thursday, August 22, 13

Slide 50

Slide 50 text

function Crocodile(name, gender) { this.name = name; this.gender = gender; } Crocodile.prototype.stalkTourists = function() { //.. }; withWalking.call(Crocodile.prototype); withSwimming.call(Crocodile.prototype); Thursday, August 22, 13

Slide 51

Slide 51 text

Flight uses functional mixins Thursday, August 22, 13

Slide 52

Slide 52 text

github.com/flightjs/example-app Thursday, August 22, 13

Slide 53

Slide 53 text

function withSelect() { this.defaultAttrs({ selectedIds: [] }); this.selectItem = function($item, append) { $item.addClass(this.attr.selectedClass); this.attr.selectedIds.push($item.attr('id')); this.trigger('uiSelectionChanged', {selIds: this.attr.selectedIds}); }; this.unselectItem = function($item) { $item.removeClass(this.attr.selectedClass); this.attr.selectedIds.splice(getIdIndex($item), 1); this.trigger('uiSelectionChanged', {selIds: this.attr.selectedIds}); }; } Thursday, August 22, 13

Slide 54

Slide 54 text

defineComponent(mailItems, withSelect); defineComponent(folders, withSelect); defineComponent(moveToSelector, withSelect); Thursday, August 22, 13

Slide 55

Slide 55 text

The Advice Mixin Thursday, August 22, 13

Slide 56

Slide 56 text

advice.js is a mixin Thursday, August 22, 13

Slide 57

Slide 57 text

advice.js is a mixin it lets you add custom code before(), after() or around() an existing function. Thursday, August 22, 13

Slide 58

Slide 58 text

all flight mixins get advice.js for free Thursday, August 22, 13

Slide 59

Slide 59 text

all flight mixins get advice.js for free so mixins can augment functions, not clobber them Thursday, August 22, 13

Slide 60

Slide 60 text

withAdvice.call(Crocodile.prototype); function withFlu() { this.before('walk', function() { console.log('sniff'); }); } var sickCrocodile = new Crocodile(); withFlu.call(sickCrocodile); sickCrocodile.walk(); //"sniff, pad, pad, pad, pad" Thursday, August 22, 13

Slide 61

Slide 61 text

function withSelect() { this.defaultAttrs({ selectedIds: [] }); this.toggleItemSelect = function(ev, data) { var $item = $(data.el), append; if ($item.hasClass(this.attr.selectedClass)) { this.unselectItem($item); } else { this.selectItem($item, isMultiSelect(ev)); } }; this.selectItem = function($item, append) {/*..*/}; this.unselectItem = function($item) {/*..*/}; this.after('initialize', function() { this.on(this.select('itemSelector'), 'click', this.toggleItemSelect); }); } Thursday, August 22, 13

Slide 62

Slide 62 text

So why do we like functional mixins? Thursday, August 22, 13

Slide 63

Slide 63 text

Mixins as verbs instead of nouns. Mixins are functions. We can take advantage of closure scope and arguments. A mixin can be applied to any object type: prototype, instance, whatever. Advice allows functional mixins to augment existing functions, not clobber them. Thursday, August 22, 13

Slide 64

Slide 64 text

Works with the language Simple to understand No surprises! Thursday, August 22, 13

Slide 65

Slide 65 text

Obrigado! @angustweets javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at- javascript-mixins/ Thursday, August 22, 13