javascript the good parts v2

58
Javascript The Good Parts Federico Galassi [email protected] http://federico.galassi.net 1

Upload: federico-galassi

Post on 15-Jan-2015

4.591 views

Category:

Technology


1 download

DESCRIPTION

Second iteration of my javascript talk. Presented at PHP Day Italia 2009 on May 15th. Slides refactored, cut down code examples and added some content about js abstractions and ecmascript 3.1. See http://federico.galassi.net/2009/05/17/javascript-the-good-parts-talk/ Follow me on Twitter! https://twitter.com/federicogalassi

TRANSCRIPT

Page 2: Javascript The Good Parts v2

‣ The language of the Web‣ A nice, elegant, expressive

language

Why Javascript

2

Page 3: Javascript The Good Parts v2

‣ A nice, elegant, expressive language...‣ What??

Javascript: really a good language?

3

Page 4: Javascript The Good Parts v2

‣ Good for web pages‣ Bad for “serious” programming

‣ large projects‣ maintainable code

Javascript perceived as a toy language

4

Page 5: Javascript The Good Parts v2

‣ Stanford UniversityCS 242 “Programming Languages” 2008

‣ Mozilla Corporation‣ Firefox

‣ Many more...

Javascript is a toy language? Bullshit!!

5

Page 6: Javascript The Good Parts v2

‣ The Most Misunderstood language ever‣ Different from mainstream‣ Design mistakes‣ Traditionally runs in the browser

Javascript is not toy language...So what?

6

Page 7: Javascript The Good Parts v2

‣ Not the language of your choice‣ You already know other good languages

‣ It’s “easy”, no need to learn‣ Copy&Paste Oriented Programming

!=

Javascript is different: not your choice

7

Page 8: Javascript The Good Parts v2

‣ Familiar syntax from Java/C‣ Pretty exotic foundations

‣Objects from Self‣Functions from Scheme

if (x < 1) { x++;}

Javascript is different: an exotic language

8

Page 9: Javascript The Good Parts v2

Javascript has design mistakes

‣ Short lab time‣ hacked in one week in may 1995‣ in Netscape 2 by the end of the year

‣ Too fast adoption‣ web boom

‣ Controversial goals‣ “easy” for non programmers‣ must look like java

‣ No fixes since 1999 ™9

Brendan EichCreator of JavascriptMozilla CTO

Page 10: Javascript The Good Parts v2

‣ Inconsistent implementations‣ poor specifications

‣ Depends on DOM for I/O‣ and it sucks!

‣ Lack of common features‣ file system access‣ sockets‣ “require”

‣ No standard libraries

Javascript usually runs in the browser

10

Page 11: Javascript The Good Parts v2

‣ The Blooming of Abstractions

Javascript: Abstractions

11

Page 12: Javascript The Good Parts v2

‣ Fix the language‣ Add events portably‣ Select DOM elements easily

Javascript: Abstractions fix it

12

YAHOO.util.Event.addListener("elementid", "click", fnCallback);

$(".myclass")

Page 13: Javascript The Good Parts v2

Javascript: Abstractions rewrite it

‣ Rewrite the language‣ Declare a “classical” class

13

var Person = new Class({ initialize: function(name){ this.name = name; }, greet: function(){ alert("hi, i am " + this.name); }});

Page 14: Javascript The Good Parts v2

‣ Language??‣ It’s a Virtual Machine!

Javascript: Abstractions ignore it

14

public class StockWatcher implements EntryPoint {

private Button addStockButton = new Button("Add"); public void onModuleLoad() { // Listen for mouse events on the Add button. addStockButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { addStock(); } }); }

Page 15: Javascript The Good Parts v2

‣ Abstractions are useful yet...‣ All non-trivial abstractions, to some degree, are

leaky.‣ Knowledge is always good

Javascript: Abstractions...beware

15

Page 16: Javascript The Good Parts v2

‣ Imperative‣ Functional‣ Object Oriented‣ Simple‣ Winner by natural selection

‣ ...where java failed.

DachshundEvolution

Javascript rules as it is!

16

Page 17: Javascript The Good Parts v2

Javascript the different good parts:Functions 1

‣ First Class Functions‣ are objects‣ can be created at runtime‣ can be stored in variables‣ can be created as anonymous literals

17

// Creation with literalvar hello = function(name) { return "hello " + name;};

// Invocationhello; // function()hello("world"); // "hello world"

Page 18: Javascript The Good Parts v2

Javascript the different good parts:Functions 2

‣ First Class Functions‣ can be passed as parameters

to functions‣ can be returned by functions

18

// Passed as parameter and invokedvar hey = function() { print "hey" };var twice = function(func) { func(); func();};twice(hey); // prints "heyhey"

// Returned by a functionvar makeHey = function() { return function() { return "hey”; }};var hey2 = makeHey();hey2(); // "hey"

Page 19: Javascript The Good Parts v2

‣ Scopes‣ Global‣ Function

‣ No block-level

Javascript the different good parts:Functions and Scope

19

function outer() {

}

function inner() {

}

g = 1

b = 2

o = 3

i = 4

Global

Function

var g = 1;

if (true) {

var b = 2;

}

var i = 4;

var o = 3;

Page 20: Javascript The Good Parts v2

‣ Scope Chain‣ Each scope

“inherits” fromthe “previous”one

Javascript the different good parts:Functions and Scope Chain

20

function outer() {

}

function inner() {

}

g = 1

b = 2

o = 3

i = 4

Scope Chain

Global

Function

var g = 1;

if (true) {

var b = 2;

}

var i = 4;

var o = 3;

Page 21: Javascript The Good Parts v2

‣ Closure:Functions“remember”their scopechain

Javascript the different good parts:Functions as Closures

21

g = 1

g = 3

Scope Chain

Global

function outer() {

var g = 3;

return

}

function() {

return g;

}

Function

var g = 1

var inner = outer();

inner(); // returns 3

Page 22: Javascript The Good Parts v2

‣ Containers of key/value pairs‣ keys are strings‣ values are anything

book

-"author"

"Javascript"

240

"title"

"pages"

"surname"

"Federico""name"

"Galassi"

// Creation with literalvar book = { title: "Javascript", pages: 240, author: { name: "Federico", surname: "Galassi" }}

Javascript the different good parts:Objects 1

22

Page 23: Javascript The Good Parts v2

// Get a propertybook["title"] // returns "Javascript"book.title // same as book["title"]book.propertyNotThere // returns undefined

// Set or update a propertybook.cover = "butterfly.jpg"book.title = "Javascript the good parts"

// Delete a propertydelete book.title // now book.title is undefined

Javascript the different good parts:Objects 2‣ Objects are dynamic

‣ Properties can be added and removed at runtime‣ No class constraints

23

Page 24: Javascript The Good Parts v2

‣ Methods arefunction valuedproperties

‣ Inside methodsthis is bound toobject “on the left”

book.read = function() { var action = "Reading "; return action + this.title;}

book.read(); // returns "Reading Javascript"

book

-"read"

"Javascript"

240

"title"

"pages"

function() {

var action = "Reading ";

return action + this.title;

}

Method

action = "Reading "

Scope

this =

Javascript the different good parts:Objects Methods

24

Page 25: Javascript The Good Parts v2

‣ Every object can be linked to another object through the special “prototype” property

‣ If a property does not exist in the object, request is delegated to its prototype

another_point

__proto__ -

20"x"

point

-__proto__

10

10

"x"

"y"

var point = { x: 10, y: 10};var another_point = Object.create(point);another_point.x = 20;

another_point.x; // returns 20another_point.y; // returns 10 (delegated)

Javascript the different good parts:Objects Prototype

25

Page 26: Javascript The Good Parts v2

‣ Delegation works for methods too‣ this is always bound to the “first object”

// returns 20 * 10 = 200another_rect.area();another_rect

__proto__ -

20"width"

rect

-__proto__

-"area"

10

10

"width"

"height" function() {

return this.width *

this.height;

}

Method

Scope

this = Prototype

Javascript the different good parts:Objects Prototype and Methods

26

Page 27: Javascript The Good Parts v2

‣ Properties are resolved by following the Prototype Chain

‣ Prototype Chains always ends with Object‣ Beyond there’s undefined

first.asdasdasd;// "asdasdasd" not in// first, second, last// "asdasdasd" not in {}// returns undefined

first.hasOwnProperty// returns function() ...

first__proto__ -

second__proto__ -

last__proto__ -

Object

Property

Resolution

Javascript the different good parts:Objects Prototype Chain

27

Page 28: Javascript The Good Parts v2

‣ Prototypes are javascript way to share‣ Data‣ Behavior

Javascript the different good parts:Objects Prototypal Inheritance 1

28

Page 29: Javascript The Good Parts v2

‣ Prototypal Inheritance‣ Vs Classical Inheritance‣ Simpler

‣ No classes and objects, only objects‣ Easier

‣ Work by examples, not abstractions‣ Powerful !!

‣ Can simulate classical‣ Reverse not true

‣ Shhhh, Don’t tell anyone‣ Easier to write spaghetti code

Javascript the different good parts:Objects Prototypal Inheritance 2

29

Page 30: Javascript The Good Parts v2

‣ Ok, I cheated‣ __proto__ available in mozilla only‣ Object.create coming in next revision of language

‣ Javascript is schizophrenic‣ Prototypal nature‣ Wannabe classical

Javascript the different good parts:Objects Prototypal Inheritance 3

30

Page 31: Javascript The Good Parts v2

Javascript the different good parts:Object Constructor 1

‣ Constructor Functions‣ Function is a class constructor‣ Function prototype is class behavior‣ new makes new objects

‣ Why?‣ feels classical‣ feels familiar

31

function Rectangle(w, h) { this.w = w; this.h = h;}Rectangle.prototype.higher =function() { this.h += 1 };

var rect = new Rectangle(5,10);

Page 32: Javascript The Good Parts v2

‣ Worst of both worlds‣ Unnecessarily complicated‣ Hide prototypal nature‣ Weird for classical programmers

Javascript the different good parts:Object Constructor 2

32

Page 33: Javascript The Good Parts v2

‣ Fortunately there’s a Quick Fix

// create an object with a given prototype

if (typeof Object.create !== 'function') { Object.create = function (o) { var F = function() {}; F.prototype = o; return new F(); };}

var siamese = Object.create(cat);

Javascript the different good parts:Objects Constructor Functions Fix

33

Page 34: Javascript The Good Parts v2

‣ No real arrays in javascript‣ They’re objects in disguise

‣ special props and methods‣ Cool literal syntax

Javascript the different good parts:Arrays

34

// array literalvar numbers = [1, 2, 3];

// nice methodsnumbers.push(4); // now [1, 2, 3, 4]

// an object indeednumbers.dog = 'pretty';

Page 35: Javascript The Good Parts v2

Javascript the different good parts:Functional Programming

‣ Iterators‣ Callbacks‣ Module Pattern‣ Memoization

35

Page 36: Javascript The Good Parts v2

‣ Take control of loops‣ Reduce accidental complexity

Javascript the different good parts:Functional Programming Iterators

36

Page 37: Javascript The Good Parts v2

// iterate on a collection

function each(arr, func) { for (var i=0; i<arr.length; i++) { func(arr[i]); }}

var ten = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

each(ten, function(i) { print i;});// prints 12345678910

Javascript the different good parts:Iterators Example 1

37

Page 38: Javascript The Good Parts v2

// maps a collection to a new one

function map(arr, func) { var result = []; each(arr, function(i) { result.push(func(i)); }); return result;}

var ten = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

map(ten, function(i) { return i * i; });// returns [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Javascript the different good parts:Iterators Example 2

38

Page 39: Javascript The Good Parts v2

// filter elements of a collection

function filter(arr, func) { var result = []; each(arr, function(i) { if (func(i)) { result.push(i); } }); return result;}

var ten = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

filter(ten, function(i) { return i % 2 === 0; });// returns [2, 4, 6, 8, 10]

Javascript the different good parts:Iterators Example 3

39

Page 40: Javascript The Good Parts v2

// compute a single value from a collection

function reduce(arr, func, start) { var result = start; each(arr, function(i) { result = func(i, result); }); return result;}

var ten = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

reduce(ten, function(i, sum) { return i + sum;}, 0);// returns 55

Javascript the different good parts:Iterators Example 4

40

Page 41: Javascript The Good Parts v2

// Composability// square elements, then pick even ones, then sum

reduce( filter( map(ten, function(i) { return i * i; } ), function(i) { return i % 2 === 0; } ), function(i, sum) { return i + sum; }, 0);

Javascript the different good parts:Iterators Example 5

41

Page 42: Javascript The Good Parts v2

// Composability but easy to read

var square = function(arr) { return map(arr, function(i) { return i * 2; });}var even = function(arr) { return filter(arr, function(i) { return i % 2 === 0; });}var sum = function(arr) { return reduce(arr, function(i, total) { return i + total; }, 0);}

sum(even(square(ten)));

Javascript the different good parts:Iterators Example 6

42

Page 43: Javascript The Good Parts v2

‣ Manage asynchronous communication‣ Hide complexity

Javascript the different good parts:Functional Programming Callbacks

43

Page 44: Javascript The Good Parts v2

// Synchronous request

var response = get("http://www.google.com");display(response);

// Asynchronous with callback

get("http://www.google.com", function(response) { display(response); });

Javascript the different good parts:Callbacks Example 1

44

Page 45: Javascript The Good Parts v2

// explicit complexityvar response = get("http://www.google.com");if (response.completed) { if (response.httpCode === "200") { display(response); } else { // http error }} else { // network error}

Javascript the different good parts:Callbacks Example 2

45

Page 46: Javascript The Good Parts v2

// complexity hidden in the client codevar response = get("http://www.google.com");if (success(response)) { display(response);} else { // error}

// complexity hidden awayget("http://www.google.com", { success: function(response) { display(response); }});

Javascript the different good parts:Callbacks Example 3

46

Page 47: Javascript The Good Parts v2

‣ Hide state and behavior

Javascript the different good parts:Functional Programming Module Pattern

47

Page 48: Javascript The Good Parts v2

var numbers = ["zero", "one", "two", "three", ...]; // GLOBAL BADvar numberToString = function(num) { return numbers[num];}

var numberToString = function(num) { // LOCAL SLOW var numbers = ["zero", "one", "two", "three", ...]; return numbers[num];}

var numberToString = function() { // PRIVATE AND FAST var numbers = ["zero", "one", "two", "three", ...]; return function(num) { return numbers[num]; }}();

Javascript the different good parts:Module Pattern Example 1

48

Page 49: Javascript The Good Parts v2

‣ Cache computation‣ Speed up execution

Javascript the different good parts:Functional Programming Memoization

49

Page 50: Javascript The Good Parts v2

// get pixels. maybe millions of themvar pixels = getImagePixels("image.jpg");

var getColor = function(pixel) { // ... computation on RGB values ... returns "black"; // or "white" or "green" etc...}

// find the colorpixels.each(function(pixel) { var color = getColor(pixel); // store result});

Javascript the different good parts:Memoization Example 1

50

Page 51: Javascript The Good Parts v2

// wasted computation on already calculated pixels// cache it...var getColorCache = function(func) { var cache; // setup cache ... return function(pixel) { if (cache.missing(pixel)) { cache.store(pixel, func(pixel)); } return cache.get(pixel); }}(getColor);

Javascript the different good parts:Memoization Example 2

51

Page 52: Javascript The Good Parts v2

‣ The features you should definitely avoid

Javascript the bad parts

52

Page 53: Javascript The Good Parts v2

// Good, returns { ok: true } // Very bad, returns undefinedreturn { return ok: true {} ok: true }

// Good // Very bad, errorbook["class"]; book.class;var book = { var book = { "class": "book" class: "book" } }

Javascript the bad parts 1

‣ Global variables‣ Semicolon insertion

‣ Reserved words

53

Page 54: Javascript The Good Parts v2

// Not useful, returns "object"typeof array;// Wrong, returns "object"typeof null;// Inconsistent, returns "function" or "object"typeof /a/;

// Good, returns 8 // Wrong, returns 0parseInt("08", 10); parseInt("08");

Javascript the bad parts 2

‣ Unicode‣ typeof

‣ parseInt

54

Page 55: Javascript The Good Parts v2

0.2 + 0.1 === 0.3 // false

arguments.join // returns undefined

if (book.name == null) { ... // 2 errors, works by coincidence

'' == '0' // false0 == '' // true0 == '0' // true

false == undefined // falsefalse == null // falsenull == undefined // true

Javascript the bad parts 3

‣ +‣ Floating Point

‣ Phony Arrays

‣ Falsy values

‣ == type coercion

55

Page 56: Javascript The Good Parts v2

var cache;var word = getWord(); // returns "constructor"if (word in cache) { // ops, true

// safe wayfor (var i in list) { if (list.hasOwnProperty(i)) { // do something }}

Javascript the bad parts 4

56

‣ Objects are not hashes

‣ Deep for..in

‣ Extending native prototypes kill kittens‣ new

‣ forgetting new makes global variables!

Page 57: Javascript The Good Parts v2

‣ ECMAScript 3.1 to Save Us‣ Object.create built-in‣ Properties enumerable/writable/configurable‣ JSON built-in‣ Properties accessors‣ Security

‣ strict mode‣ object “lock down”

‣ Coming Soon On Your Browser!

Javascript the bad parts: ES3.1 Salvation

57

Page 58: Javascript The Good Parts v2

‣ Thank to Douglas Crockford and his book‣ He knows the way

Credits

58