Javascript The Good Parts v2

Post on 15-Jan-2015

4.591 views 1 download

Tags:

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 of Javascript The Good Parts v2

Javascript The Good Parts

Federico Galassifederico.galassi@gmail.com

http://federico.galassi.net

1

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

language

Why Javascript

2

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

Javascript: really a good language?

3

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

‣ large projects‣ maintainable code

Javascript perceived as a toy language

4

‣ Stanford UniversityCS 242 “Programming Languages” 2008

‣ Mozilla Corporation‣ Firefox

‣ Many more...

Javascript is a toy language? Bullshit!!

5

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

Javascript is not toy language...So what?

6

‣ 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

‣ 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

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

‣ 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

‣ The Blooming of Abstractions

Javascript: Abstractions

11

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

Javascript: Abstractions fix it

12

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

$(".myclass")

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); }});

‣ 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(); } }); }

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

leaky.‣ Knowledge is always good

Javascript: Abstractions...beware

15

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

‣ ...where java failed.

DachshundEvolution

Javascript rules as it is!

16

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"

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"

‣ 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;

‣ 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;

‣ 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

‣ 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

// 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

‣ 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

‣ 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

‣ 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

‣ 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

‣ Prototypes are javascript way to share‣ Data‣ Behavior

Javascript the different good parts:Objects Prototypal Inheritance 1

28

‣ 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

‣ 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

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

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

Javascript the different good parts:Object Constructor 2

32

‣ 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

‣ 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';

Javascript the different good parts:Functional Programming

‣ Iterators‣ Callbacks‣ Module Pattern‣ Memoization

35

‣ Take control of loops‣ Reduce accidental complexity

Javascript the different good parts:Functional Programming Iterators

36

// 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

// 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

// 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

// 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

// 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

// 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

‣ Manage asynchronous communication‣ Hide complexity

Javascript the different good parts:Functional Programming Callbacks

43

// 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

// 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

// 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

‣ Hide state and behavior

Javascript the different good parts:Functional Programming Module Pattern

47

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

‣ Cache computation‣ Speed up execution

Javascript the different good parts:Functional Programming Memoization

49

// 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

// 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

‣ The features you should definitely avoid

Javascript the bad parts

52

// 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

// 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

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

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!

‣ 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

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

Credits

58