Javascript The Good Parts

Post on 06-May-2015

4.576 views 1 download

description

By Federico Galassi and Gabriele Lana at PHPCon Italia 2009 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

Javascript The Good Parts

Gabriele Lanagabriele.lana@gmail.com

Federico Galassifederico.galassi@gmail.com

Why Javascript

The language of the Web A nice, elegant, expressive

language

2

Why Javascript

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

3

Javascript perceived as a toy language

Good for small quick web hacks Not good for “serious” programming

large projects mantainable code

4

Javascript is a toy language? Bullshit!!

Stanford UniversityCS 242 “Programming Languages” 2008

Mozilla Corporation Firefox

Many more...

5

Javascript is not toy language...So what?

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

6

Javascript is different

Not the language you already know You already know other good languages It’s a web designer thing, it’s “easy” Copy&Paste Oriented Programming

7

!=

Javascript is different

Hidden nature Familiar syntax from Java/C Pretty exotic foundations

Objects from Self Functions from Scheme

8

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

Javascript has design mistakes

Short lab time hacked in one week in may 1995 in netscape2 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

Javascript usually runs in the browser

Inconsistent implementations poor specifications

Depends on DOM for I/O and it sucks!

Lack of common features file system access sockets “require”

No standard libs

10

Javascript rules indeed!

Imperative Functional Object Oriented Simple Winner by natural selection

...where java failed.

11

DachshundEvolution

Javascript can be made even better!

Javascript has good and bad parts Use good parts the “right way” Cut bad parts ...Beautiful code

12

BEFORE

AFTER

Javascript the different good parts:Functions First class

are objects can be created at runtime can be stored in variables can be passed as parameters to functions can be returned by functions can be expressed as anonymous literals

13

Javascript the different good parts:Working with Functions 1

14

// Creation the old wayfunction hello(name) { return "hello " + name;}

// Creation the good wayvar hello = function(name) { return "hello " + name;};

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

// Self Invocation(function(name) { return "hello " + name })("world");

// Passed as parameter and invokedvar helloWorld = function() { print "hello world!" };var twice = function(func) { func(); func();};

twice(helloWorld); // prints "hello world!hello world!"

// Returned by a functionvar makeHello = function() { return function(name) { return "hello " + name; }};

var hello = makeHello();hello("world"); // returns "hello world"

Javascript the different good parts:Working with Functions 2

15

Javascript the different good parts:Functions and Scope Scopes

Global Function No

Block-level Call

Objects Scope

Chain

16

var x = 1,

y = 2;

function outer(p) {

var z = 3;

}

function inner() {

var x = 100,

w = 200;

}

x = 1

y = 2

v = 3

z = 3

p = ...

x = 100

w = 200

Scope Chain

Global

Function

if (true) {

var v = 3;

}

Javascript the different good parts:Functions as Closures 1 Lexical Scoping Closures

17

z = 100

z = 3

Scope Chain

Global

function outer() {

var z = 3;

return

}

function() {

return z;

}

Function

var inner = outer();

var z = 100;

inner(); // returns 3 Execution

Javascript the different good parts:Functions as Closures 2 Closures bind variables, not values !

18

// Wrongvar funcs = [];for (var i = 0; i < 3; i++) { funcs[i] = function() { return i; }}

funcs[0](); // returns 3 !!funcs[1](); // returns 3 !!funcs[2](); // returns 3 !!

// Rightvar funcs = [];for (var i = 0; i < 3; i++) { funcs[i] = function(p) { return function() {return p}; }(i)}

funcs[0](); // returns 0funcs[1](); // returns 1funcs[2](); // returns 2

Javascript the different good parts:Objects 1 Containers of key/value pairs (properties)

keys are strings values are anything (loose typing)

19

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 2 Objects are dynamic

Properties can be added and removed at runtime No class constraints

20

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

function valuedproperties

Inside methodsthis is bound toobject “on the left”

21

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 Prototype Every object can be linked to another object

through the prototype property (__proto__) If a property does not exist in the object, request is

delegated to the prototype

22

another_point

__proto__ -

20"x"

point

-__proto__

10

10

"x"

"y"

var point = { x: 10, y: 10};var another_point = { x: 20};another_point.__proto__ = point;point.x; // returns 20point.y; // returns 10 (delegated)

Javascript the different good parts:Objects Prototype and Methods Delegation works for methods too this is always bound to the “first object”

23

// 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 Chain Prototypes form a chain, followed to resolve

properties At the end there is Object which provides common

stuff, then undefined

24

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

var car = { color: "white", speed: 0, accel: function(kmh) { this.speed += kmh; }};

// Make a supercar from carvar supercar = { color: "black", __proto__: car};

// or also by cloningvar supercar = Object.create(car, { color: "black"});

Javascript the different good parts:Working with Objects and Prototypes 1

25

// Prototype relationship is dynamiccar.wheels = 4;supercar.wheels; // 4

// Setting properties is localsupercar.driver = "M. Knight";car.driver; // undefined

// Where properties are from?"driver" in supercar; // true"wheels" in supercar; // truesupercar.hasOwnProperty("driver"); // truesupercar.hasOwnProperty("wheels"); // false

// Common to all objectssupercar.toString(); // "[object Object]"car.isPrototypeOf(supercar); // true

Javascript the different good parts:Working with Objects and Prototypes 2

26

Javascript the different good parts:Objects Prototypal Inheritance 1 Prototypes are javascript way to share

Data Behaviour

27

Javascript the different good parts:Objects Prototypal Inheritance 2 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

28

Javascript the different good parts:Objects Prototypal Inheritance 3 Ok, I cheated

__proto__ available in mozilla only Object.create coming in next revision of language

Javascript is schizophrenic Prototypal nature Wannabe classical

29

Javascript the different good parts:Objects Constructor Functions 1 Constructor Functions

Boring Function has a “prototype” property The “prototype” property has a

“constructor” property which pointsback to the Function object

Function can be invoked with the“new” operator

Create an object whose __proto__is “prototype” property of Function

Initialize the object executing Function

30

// Constructor function // silently executesfunction Dog(name) { // Dog.prototype = { constructor: Dog } this.name = name;}

Dog.prototype; // ObjectDog.prototype.constructor; // return function Dog

// Create a new Dog object // silently executesvar fido = new Dog("fido"); // var fido = Object.create(Dog.prototype); // Dog.call(fido, "fido");

fido.__proto__; // Objectfido.__proto__.constructor; // Dogfido.constructor; // Dog (inherited by __proto__)fido.name // fido

Javascript the different good parts:Objects Constructor Functions 2

31

Javascript the different good parts:Objects Constructor Functions 3 Why?

Function is a constructor Function prototype is a class new is new Feels classical, Feels familiar

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

32

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

var rect = new Rectangle(5,10);

Javascript the different good parts:Objects Constructor Functions Fix Fortunately there’s a Quick Fix

33

// waiting for next javascript implementation...

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

Javascript the different good parts:Arrays No real arrays in javascript They’re objects in disguise

special props and methods Cool literal syntax

34

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

// referencenumbers[2]; // returns 3numbers[10]; // returns undefined

// length propertynumbers.length; // 5

// nice methodsnumbers.push(11); // now [1, 2, 3, 4, 5, 11]numbers.join(" "); // returns "1 2 3 4 5 11"

Javascript the different good parts:Arrays Example 1

35

// actually...

// indexes are just object propertiesnumbers.2; // would return 3

// common object methodsnumbers.hasOwnProperty(0); // returns true

// length = last numeric prop + 1numbers[100] = 100;numbers.length; // returns 101

// ultimate prooftypeof numbers; // returns "object"

Javascript the different good parts:Arrays Example 2

36

Javascript the different good parts:Functional Programming Iterators Callbacks Module Pattern Curry Memoization

37

Javascript the different good parts:Functional Programming Iterators Take control of loops Reduce accidental complexity

38

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

39

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

40

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

41

// 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;});// returns 55

Javascript the different good parts:Iterators Example 4

42

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

43

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

44

Javascript the different good parts:Functional Programming Callbacks Manage asynchronous communication Hide complexity

45

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

46

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

47

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

48

Javascript the different good parts:Functional Programming Module Pattern Hide state and behaviour

49

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

50

Javascript the different good parts:Functional Programming Memoization Cache computation Speed up execution

51

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

52

// wasted computation, 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

53

Javascript the bad parts

The features you should definitely avoid

54

Javascript the bad parts 1

Global variables Semicolon insertion

Reserved words

55

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

Unicode typeof

parseInt

56

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

+ Floating Point

Phony Arrays

Falsy values

== type coercion

57

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 4

Objects are not hashes

Deep for..in

Extending native prototypes kill kittens Prototype library mess

58

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

Credits

Thank to Douglas Crockford and his book He knows the way

59