Download - Javascript The Good Parts v2

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