This document discusses the good parts of Javascript. It argues that while Javascript has some design mistakes and inconsistencies due to its rushed creation, it is a powerful and misunderstood language. The document highlights some of Javascript's good features, including functions as first-class objects, closures, objects and prototypal inheritance, and arrays. It advocates focusing on Javascript's strengths rather than its weaknesses.
4. Javascript perceived as a toy language
Good for small quick web hacks
Not good for “serious” programming
large projects
mantainable code
4
5. Javascript is a toy language? Bullshit!!
Stanford University
CS 242 “Programming Languages” 2008
Mozilla Corporation
Firefox
Many more...
5
6. Javascript is not toy language...So what?
The Most Misunderstood language ever
Different from mainstream
Design mistakes
Traditionally runs in the browser
6
7. 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
8. Javascript is different
Hidden nature
Familiar syntax from Java/C
Pretty exotic foundations
Objects from Self
Functions from Scheme
if (x < 1) {
x++;
}
8
9. 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
Brendan Eich
No fixes since 1999 Creator of Javascript
Mozilla CTO
9
10. 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
12. Javascript can be made even better!
Javascript has good and bad parts
Use good parts the “right way”
Cut bad parts
...Beautiful code AFTER
BEFORE
12
13. 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
14. Javascript the different good parts:
Working with Functions 1
// Creation the old way
function hello(name) {
return quot;hello quot; + name;
}
// Creation the good way
var hello = function(name) {
return quot;hello quot; + name;
};
// Invocation
hello; // returns function()
hello(quot;worldquot;); // returns quot;hello worldquot;
// Self Invocation
(function(name) { return quot;hello quot; + name })(quot;worldquot;);
14
15. Javascript the different good parts:
Working with Functions 2
// Passed as parameter and invoked
var helloWorld = function() { print quot;hello world!quot; };
var twice = function(func) {
func(); func();
};
twice(helloWorld); // prints quot;hello world!hello world!quot;
// Returned by a function
var makeHello = function() {
return function(name) {
return quot;hello quot; + name;
}
};
var hello = makeHello();
hello(quot;worldquot;); // returns quot;hello worldquot;
15
16. Javascript the different good parts:
Functions and Scope
Scopes Global
var x = 1, x=1
y = 2; y=2
Global v=3
Function
function outer(p) {
Function var z = 3;
function inner() {
No z=3
var x = 100,
Block-level p = ...
w = 200;
Call }
Objects } x = 100
w = 200
if (true) {
Scope var v = 3;
Chain Scope Chain
}
16
17. Javascript the different good parts:
Functions as Closures 1
Lexical Scoping
Closures Global z = 100
Function
function outer() {
var z = 3;
return function() {
return z; z=3
}
}
var inner = outer();
var z = 100;
ion
Execut
inner(); // returns 3 Scope Chain
17
18. Javascript the different good parts:
Functions as Closures 2
Closures bind variables, not values !
// Wrong // Right
var funcs = []; var funcs = [];
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
funcs[i] = function() { funcs[i] = function(p) {
return i; return function() {return p};
} }(i)
} }
funcs[0](); // returns 3 !! funcs[0](); // returns 0
funcs[1](); // returns 3 !! funcs[1](); // returns 1
funcs[2](); // returns 3 !! funcs[2](); // returns 2
18
19. Javascript the different good parts:
Objects 1
Containers of key/value pairs (properties)
keys are strings
values are anything (loose typing)
// Creation with literal
book
var book = {
quot;titlequot; quot;Javascriptquot; title: quot;Javascriptquot;,
pages: 240,
quot;pagesquot; 240
author: {
quot;authorquot; -
name: quot;Federicoquot;,
surname: quot;Galassiquot;
}
}
quot;namequot; quot;Federicoquot;
quot;surnamequot; quot;Galassiquot;
19
20. Javascript the different good parts:
Objects 2
Objects are dynamic
Properties can be added and removed at runtime
No class constraints
// Get a property
book[quot;titlequot;] // returns quot;Javascriptquot;
book.title // same as book[quot;titlequot;]
book.propertyNotThere // returns undefined
// Set or update a property
book.cover = quot;butterfly.jpgquot;
book.title = quot;Javascript the good partsquot;
// Delete a property
delete book.title // now book.title is undefined
20
21. Javascript the different good parts:
Objects Methods
Methods are book
function valued quot;titlequot; quot;Javascriptquot;
properties quot;pagesquot; 240
quot;readquot; -
Inside methods
Method
this is bound to
function() {
object “on the left” var action = quot;Reading quot;;
return action + this.title;
book.read = function() {
}
var action = quot;Reading quot;;
return action + this.title;
Scope
}
action = quot;Reading quot;
this =
book.read(); // returns quot;Reading Javascriptquot;
21
22. 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
another_point
var point = {
quot;xquot; 20
x: 10,
y: 10 __proto__ -
};
var another_point = {
x: 20
point
};
quot;xquot; 10
another_point.__proto__ = point;
point.x; // returns 20 quot;yquot; 10
point.y; // returns 10 (delegated)
__proto__ -
22
23. Javascript the different good parts:
Objects Prototype and Methods
Delegation works for methods too
this is always bound to the “first object”
another_rect // returns 20 * 10 = 200
another_rect.area();
quot;widthquot; 20
Scope
__proto__ -
this =
Prototype
rect
Method
quot;widthquot; 10
function() {
quot;heightquot; 10
return this.width *
quot;areaquot; - this.height;
}
__proto__ -
23
24. 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 first.asdasdasd;
// quot;asdasdasdquot; not in first,
first // second, last
// quot;asdasdasdquot; not in {}
__proto__ -
// returns undefined
Pr luti
Re
op
so
second er on
first.hasOwnProperty
ty // returns function() ...
__proto__ -
Object
last
__proto__ -
24
25. Javascript the different good parts:
Working with Objects and Prototypes 1
var car = {
color: quot;whitequot;,
speed: 0,
accel: function(kmh) {
this.speed += kmh;
}
};
// Make a supercar from car
var supercar = {
color: quot;blackquot;,
__proto__: car
};
// or also by cloning
var supercar = Object.create(car, {
color: quot;blackquot;
});
25
26. Javascript the different good parts:
Working with Objects and Prototypes 2
// Prototype relationship is dynamic
car.wheels = 4;
supercar.wheels; // 4
// Setting properties is local
supercar.driver = quot;M. Knightquot;;
car.driver; // undefined
// Where properties are from?
quot;driverquot; in supercar; // true
quot;wheelsquot; in supercar; // true
supercar.hasOwnProperty(quot;driverquot;); // true
supercar.hasOwnProperty(quot;wheelsquot;); // false
// Common to all objects
supercar.toString(); // quot;[object Object]quot;
car.isPrototypeOf(supercar); // true
26
27. Javascript the different good parts:
Objects Prototypal Inheritance 1
Prototypes are javascript way to share
Data
Behaviour
27
28. 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
29. 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
30. 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 points
back 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
31. Javascript the different good parts:
Objects Constructor Functions 2
// Constructor function // silently executes
function Dog(name) { // Dog.prototype = { constructor: Dog }
this.name = name;
}
Dog.prototype; // Object
Dog.prototype.constructor; // return function Dog
// Create a new Dog object // silently executes
var fido = new Dog(quot;fidoquot;); // var fido = Object.create(Dog.prototype);
// Dog.call(fido, quot;fidoquot;);
fido.__proto__; // Object
fido.__proto__.constructor; // Dog
fido.constructor; // Dog (inherited by __proto__)
fido.name // fido
31
32. Javascript the different good parts:
Objects Constructor Functions 3
function Rectangle(w, h) {
Why? this.w = w;
Function is a constructor
this.h = h;
}
Function prototype is a class
Rectangle.prototype.higher =
function() { this.h += 1 };
new is new
Feels classical, Feels familiar
var rect = new Rectangle(5,10);
Worst of both worlds
Unnecessarily complicated
Hide prototypal nature
Weird for classical programmers
32
33. Javascript the different good parts:
Objects Constructor Functions Fix
Fortunately there’s a Quick Fix
// waiting for next javascript implementation...
if (typeof Object.create !== 'function') {
Object.create = function (o) {
var F = function() {};
F.prototype = o;
return new F();
};
}
33
34. Javascript the different good parts:
Arrays
No real arrays in javascript
They’re objects in disguise
special props and methods
Cool literal syntax
34
35. Javascript the different good parts:
Arrays Example 1
// array literal
var numbers = [1, 2, 3, 4, 5];
// reference
numbers[2]; // returns 3
numbers[10]; // returns undefined
// length property
numbers.length; // 5
// nice methods
numbers.push(11); // now [1, 2, 3, 4, 5, 11]
numbers.join(quot; quot;); // returns quot;1 2 3 4 5 11quot;
35
36. Javascript the different good parts:
Arrays Example 2
// actually...
// indexes are just object properties
numbers.2; // would return 3
// common object methods
numbers.hasOwnProperty(0); // returns true
// length = last numeric prop + 1
numbers[100] = 100;
numbers.length; // returns 101
// ultimate proof
typeof numbers; // returns quot;objectquot;
36
37. Javascript the different good parts:
Functional Programming
Iterators
Callbacks
Module Pattern
Curry
Memoization
37
38. Javascript the different good parts:
Functional Programming Iterators
Take control of loops
Reduce accidental complexity
38
39. Javascript the different good parts:
Iterators Example 1
// 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
39
40. Javascript the different good parts:
Iterators Example 2
// 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]
40
41. Javascript the different good parts:
Iterators Example 3
// 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]
41
42. Javascript the different good parts:
Iterators Example 4
// 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
42
43. Javascript the different good parts:
Iterators Example 5
// 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
);
43
44. Javascript the different good parts:
Iterators Example 6
// 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)));
44
45. Javascript the different good parts:
Functional Programming Callbacks
Manage asynchronous communication
Hide complexity
45
46. Javascript the different good parts:
Callbacks Example 1
// Synchronous request
var response = get(quot;http://www.google.comquot;);
display(response);
// Asynchronous with callback
get(quot;http://www.google.comquot;, function(response) {
display(response);
});
46
47. Javascript the different good parts:
Callbacks Example 2
// explicit complexity
var response = get(quot;http://www.google.comquot;);
if (response.completed) {
if (response.httpCode === quot;200quot;) {
display(response);
} else {
// http error
}
} else {
// network error
}
47
48. Javascript the different good parts:
Callbacks Example 3
// complexity hidden in the client code
var response = get(quot;http://www.google.comquot;);
if (success(response)) {
display(response);
} else {
// error
}
// complexity hidden away
get(quot;http://www.google.comquot;, {
success: function(response) {
display(response);
}
});
48
49. Javascript the different good parts:
Functional Programming Module Pattern
Hide state and behaviour
49
50. Javascript the different good parts:
Module Pattern Example 1
var numbers = [quot;zeroquot;, quot;onequot;, quot;twoquot;, quot;threequot;, ...]; // GLOBAL BAD
var numberToString = function(num) {
return numbers[num];
}
var numberToString = function(num) { // LOCAL SLOW
var numbers = [quot;zeroquot;, quot;onequot;, quot;twoquot;, quot;threequot;, ...];
return numbers[num];
}
var numberToString = function() { // PRIVATE AND FAST
var numbers = [quot;zeroquot;, quot;onequot;, quot;twoquot;, quot;threequot;, ...];
return function(num) {
return numbers[num];
}
}();
50
51. Javascript the different good parts:
Functional Programming Memoization
Cache computation
Speed up execution
51
52. Javascript the different good parts:
Memoization Example 1
// get pixels. maybe millions of them
var pixels = getImagePixels(quot;image.jpgquot;);
var getColor = function(pixel) {
// ... computation on RGB values ...
returns quot;blackquot;; // or quot;whitequot; or quot;greenquot; etc...
}
// find the color
pixels.each(function(pixel) {
var color = getColor(pixel);
// store result
});
52
53. Javascript the different good parts:
Memoization Example 2
// 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);
53
55. Javascript the bad parts 1
Global variables
Semicolon insertion
// Good, returns { ok: true } // Very bad, returns undefined
return { return
ok: true {
} ok: true
}
Reserved words
// Good // Very bad, error
book[quot;classquot;]; book.class;
var book = { var book = {
quot;classquot;: quot;bookquot; class: quot;bookquot;
} }
55
56. Javascript the bad parts 2
Unicode
typeof
// Not useful, returns quot;objectquot;
typeof array;
// Wrong, returns quot;objectquot;
typeof null;
// Inconsistent, returns quot;functionquot; or quot;objectquot;
typeof /a/;
parseInt
// Good, returns 8 // Wrong, returns 0
parseInt(quot;08quot;, 10); parseInt(quot;08quot;);
56
57. Javascript the bad parts 3
+
Floating Point
0.2 + 0.1 === 0.3 // false
Phony Arrays
arguments.join // returns undefined
Falsy values
if (book.name == null) { ... // 2 errors, works by coincidence
== type coercion
'' == '0' // false false == undefined // false
0 == '' // true false == null // false
0 == '0' // true null == undefined // true
57
58. Javascript the bad parts 4
Objects are not hashes
var cache;
var word = getWord(); // returns quot;constructorquot;
if (word in cache) { // ops, true
Deep for..in
// safe way
for (var i in list) {
if (list.hasOwnProperty(i)) {
// do something
}
}
Extending native prototypes kill kittens
Prototype library mess
58