Slide 1

Slide 1 text

Parlez-vous JavaScript? @angustweets

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

I work at Twitter. We work with JavaScript. Not against it.

Slide 4

Slide 4 text

“The grain tells you which way the wood wants to be cut” Charles Miller fishbowl.pastiche.org

Slide 5

Slide 5 text

Episode 1 The Accidental Tourist

Slide 6

Slide 6 text

The Problem

Slide 7

Slide 7 text

(weird shit) JAVA!! But Easier!! (Deceptively Familiar Syntax) (weird shit) WTF?

Slide 8

Slide 8 text

JavaScript Ruby Python Java Shell PHP C C++ 21% 13% 8% 8% 8% 7% 6% 4% github.com/languages

Slide 9

Slide 9 text

If languages were vacation destinations, JavaScript would be Paris

Slide 10

Slide 10 text

How not to pack for JavaScript

Slide 11

Slide 11 text

C++ RUBY JavaScript To:

Slide 12

Slide 12 text

JavaScript To: strong typing static ‘this’ second class functions OOP

Slide 13

Slide 13 text

Episode 2 Do as the Locals Do...

Slide 14

Slide 14 text

The Five Hills of JavaScript...

Slide 15

Slide 15 text

closures first-class functions dynamic ‘this’ prototypes call/apply

Slide 16

Slide 16 text

Episode 3 OOP not spoken here

Slide 17

Slide 17 text

OK, I lied Constructor-Prototype chaining* is OOP *having one custom prototype extend another

Slide 18

Slide 18 text

But it’s awkward and unnatural...

Slide 19

Slide 19 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();

Slide 20

Slide 20 text

Object.create liberates prototype chaining from constructors.

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

ES 6 is giving us class. Some libraries have there own versions.

Slide 23

Slide 23 text

//Prototype.js var SwimmingAnimal = Class.create(Animal, { type: 'SwimmingAnimal', speak: function($super) { return $super() + ", glug"; } }); //Dustin Diaz's "klass" var Alien = SuperHuman.extend({ beam: function() { this.supr(); // beam into space } });

Slide 24

Slide 24 text

Do you even want classes?

Slide 25

Slide 25 text

Animal Walking Animal Swimming Animal Flying Animal Cat Elephant Crocodile Whale Eagle Bat Egg-laying Animal Migrating Animal

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Migrating Animal Egg-laying Animal Flying Animal Swimming Animal Walking Animal Duck? Animal Cat Elephant Crocodile Whale Eagle Bat

Slide 28

Slide 28 text

This hierarchy monster is not fussy es6 class Object.create class framework new Constructor

Slide 29

Slide 29 text

However.

Slide 30

Slide 30 text

The sad thing is that anyone even cares about inheritance hierarchies... Because in JavaScript they’re quite unnecessary...

Slide 31

Slide 31 text

Episode 4 JavaScript Mixins

Slide 32

Slide 32 text

Property Copy Mixins...

Slide 33

Slide 33 text

var withWalking = { walk: function() { console.log('walking'); }, turn: function(direction) { console.log('turning', direction); }, stopWalking: function() { console.log('stopped walking'); } };

Slide 34

Slide 34 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);

Slide 35

Slide 35 text

Functional Mixins...

Slide 36

Slide 36 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'); }; };

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

Episode 5 Monkey Patching: The Good Parts

Slide 39

Slide 39 text

https://twitter.com/rockstar_/status/147367323488108544

Slide 40

Slide 40 text

Q. How do you patch a 3rd party library without touching it?

Slide 41

Slide 41 text

A. Wrap it.

Slide 42

Slide 42 text

// Using underscore _.each = _.wrap(_.each, function(each, collection, fn, context) { each(collection, fn, context); return collection; } ); _.each([1,2,3], alert); //[1,2,3]

Slide 43

Slide 43 text

Also, why are you still using underscore when there’s...

Slide 44

Slide 44 text

github.com/kriskowal/es5-shim

Slide 45

Slide 45 text

Episode 6 Functional

Slide 46

Slide 46 text

High Order Functions

Slide 47

Slide 47 text

var fruit = ["grape ", "pear ", "apple"]; var result = []; for (var i = 0; i < fruit.length; i++) { result.push(fruit[i].trim()); } result; //["grape", "pear", "apple"]

Slide 48

Slide 48 text

fruit.map(function(each) { return each.trim(); });

Slide 49

Slide 49 text

function globalize(methodName) { return function(obj) { return obj[methodName](); } }

Slide 50

Slide 50 text

fruit.map(function(each) { return each.trim(); });

Slide 51

Slide 51 text

fruit.map(globalize('trim'));

Slide 52

Slide 52 text

Currying* (partial application) *yes I know it’s not technically currying

Slide 53

Slide 53 text

add curry 7 .curry(7) var add7= add7(5); //12 add(x,y) 5 7

Slide 54

Slide 54 text

Function.prototype.curry = function() { if (arguments.length < 1) { //nothing to curry with - return function return this; } var method = this; var args = [].slice.call(arguments); return function() { return method.apply( this, args.concat([].slice.call(arguments))); } }

Slide 55

Slide 55 text

Function Composition

Slide 56

Slide 56 text

Math.pow alert

Slide 57

Slide 57 text

alert( ) Math.pow Math.pow var alertPower = alert.compose(Math.pow);

Slide 58

Slide 58 text

Function.prototype.compose = function(argFunction) { var invokingFunction = this; return function() { return invokingFunction.call( this,argFunction.apply(this,arguments)); } }

Slide 59

Slide 59 text

Currying + Composition =

Slide 60

Slide 60 text

var sliceToRegEx = ''.slice.curry(0).compose(''.search); var parseAlpha = sliceToRegEx.curry(/[^ a-zA-Z]/); parseAlpha("[email protected]") //"fredfrith"

Slide 61

Slide 61 text

Episode 7 Beware of imitations...

Slide 62

Slide 62 text

San Francisco is great etc. But...

Slide 63

Slide 63 text

San Francisco is great etc. But... its fire hydrants are non-standard

Slide 64

Slide 64 text

EveryOther Fire Dept. wtf.sf?! SFFD X

Slide 65

Slide 65 text

jQuery is great etc. But...

Slide 66

Slide 66 text

jQuery is great etc. But... it’s objects are non-standard

Slide 67

Slide 67 text

//jQuery selectors return jQuery objects var anchors = $('a'); Array.isArray(anchors); //false

Slide 68

Slide 68 text

//jQuery selectors return jQuery objects var anchors = $('a'); Array.isArray(anchors); //false anchors.push; //function push() { [native code] } anchors.forEach; //undefined

Slide 69

Slide 69 text

//jQuery selectors return jQuery objects var anchors = $('a'); Array.isArray(anchors); //false anchors.push; //function push() { [native code] } anchors.forEach; //undefined //which means we are stuck in jquery land var hrefs = anchors.map( function(i, elem) {return elem.href} ); !!

Slide 70

Slide 70 text

//jQuery selectors return jQuery objects var anchors = $('a'); Array.isArray(anchors); //false anchors.push; //function push() { [native code] } anchors.forEach; //undefined //which means we are stuck in jquery land var hrefs = anchors.map( function(i, elem) {return elem.href} ); //perpetually Array.isArray(hrefs); //false ;-( !!

Slide 71

Slide 71 text

Unless you do this...

Slide 72

Slide 72 text

var anchors = $('a'); Array.isArray(anchors); //false hrefs = [].map.call(anchors, function(elem) {return elem.href} ); Array.isArray(hrefs); //true :)

Slide 73

Slide 73 text

or this...

Slide 74

Slide 74 text

var anchors = $('a'); Array.isArray(anchors); //false var anchors = [].slice.call(anchors); Array.isArray(anchors); //true

Slide 75

Slide 75 text

Episode 8 Everyday JavaScript

Slide 76

Slide 76 text

you could do this...

Slide 77

Slide 77 text

function getEventTarget(evt) { if (!evt) { evt = window.event; } if (!evt) { return; } var target; if (evt.target) { target = evt.target; } else { target = evt.srcElement; } return target; }

Slide 78

Slide 78 text

or you could do this...

Slide 79

Slide 79 text

function getEventTarget(evt) { evt = evt || window.event; return evt && (evt.target || evt.srcElement); }

Slide 80

Slide 80 text

Episode 9 Too long; fell asleep?

Slide 81

Slide 81 text

“Every language has its own way. Follow its form. Don’t try to program as if you were using another language.” Marijn Haverbeke Eloquent JavaScript

Slide 82

Slide 82 text

Questions? @angustweets speakerdeck.com/anguscroll/parlez-vous-javascript