js in the open

74
JS in the open (or JS in the wild) Friday, November 9, 12

Upload: victor-porof

Post on 15-Jan-2015

297 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Js in the open

JS in the open(or JS in the wild)

Friday, November 9, 12

Page 2: Js in the open

@victorporof

Programmer at Mozilla

Friday, November 9, 12

Page 3: Js in the open

The JavaScript you probably know

Friday, November 9, 12

Page 4: Js in the open

Number

String

Boolean

Object (Function, Array, Date, RegExp ...)

Function

Null

Undefined

Friday, November 9, 12

Page 5: Js in the open

typeof 3 == “number”

typeof “Gangnam Style” == “string”

typeof false == “boolean”

typeof document == “object”

typeof document.getElementById == “object”

typeof null == “object”

typeof undefined == “undefined”

Friday, November 9, 12

Page 6: Js in the open

new Number(3)

new String(“Gangnam Style”)

new Boolean(false)

Friday, November 9, 12

Page 7: Js in the open

typeof new Number(3) == “object”

typeof new String(“Gangnam Style”) == “object”

typeof new Boolean(false) == “object”

Friday, November 9, 12

Page 8: Js in the open

typeof new Number(3) == “object”

typeof new String(“Gangnam Style”) == “object”

typeof new Boolean(false) == “object”

Constructors

Friday, November 9, 12

Page 9: Js in the open

JavaScript is fundamentally about Objects

Friday, November 9, 12

Page 10: Js in the open

The JavaScript you probably don’t know

Friday, November 9, 12

Page 11: Js in the open

Friday, November 9, 12

Page 12: Js in the open

2006

Functional collectors

Array extras

Array and String generics

for each..in loops

new in JavaScript 1.6

Friday, November 9, 12

Page 13: Js in the open

Functional collectors

every(), filter(), forEach(), map(), some()

new in JavaScript 1.6

function isBigEnough(element, index, array) { return (element >= 10);}

var passed = [12, 5, 8, 130, 44].every(isBigEnough);// passed is false

var passed = [12, 54, 18, 130, 44].every(isBigEnough);// passed is true

Friday, November 9, 12

Page 14: Js in the open

Functional collectors

every(), filter(), forEach(), map(), some()

new in JavaScript 1.6

function fuzzyPlural(single) { var result = single.replace(/o/g, 'e'); return result;}

var words = ["foot", "goose", "moose", "kangaroo"];console.log(words.map(fuzzyPlural));

// ["feet", "geese", "meese", "kangaree"]

Friday, November 9, 12

Page 15: Js in the open

Array extras

indexOf(), lastIndexOf()

new in JavaScript 1.6

var array = [2, 5, 9, 2];var index = array.lastIndexOf(2);// index is 3index = array.lastIndexOf(7);// index is -1index = array.lastIndexOf(2, 3);// index is 3index = array.lastIndexOf(2, 2);// index is 0index = array.lastIndexOf(2, -1);// index is 3

Friday, November 9, 12

Page 16: Js in the open

Array and String generics

new in JavaScript 1.6

function isLetter(character) { return (character >= "a" && character <= "z");} if (Array.prototype.every.call(str, isLetter)) { alert("The string '" + str + "' contains only letters!");}

Friday, November 9, 12

Page 17: Js in the open

for each..in loops

new in JavaScript 1.6

var sum = 0;var obj = { prop1: 5, prop2: 13, prop3: 8 };

for (var item in obj) { sum += item;}print(sum); // prints 0prop1prop2prop3

Friday, November 9, 12

Page 18: Js in the open

for each..in loops

new in JavaScript 1.6

var sum = 0;var obj = { prop1: 5, prop2: 13, prop3: 8 };

for each (var item in obj) { sum += item;}print(sum); // prints "26", which is 5+13+8

Friday, November 9, 12

Page 19: Js in the open

2007

Generators

Iterators

Array comprehensions

let statements, expressions, definitions

destructuring assignment

multiple value returns & looping across objects

new in JavaScript 1.7

Friday, November 9, 12

Page 20: Js in the open

Generators

new in JavaScript 1.7

function fib() { var i = 0, j = 1; while (true) { yield i; var t = i; i = j; j += t; }} var g = fib();for (var i = 0; i < 10; i++) { console.log(g.next());}

Friday, November 9, 12

Page 21: Js in the open

Iterators

new in JavaScript 1.7

var obj = { name: "Jack Bauer", username: "JackB", id: 12345, agency: "CTU", region: "Los Angeles"}; obj.__iterator__ = function() { for (let item in this) { if (item != "id") { yield this[item]; } }};

for (let item in obj) { alert(item);}

Friday, November 9, 12

Page 22: Js in the open

Array comprehensions

new in JavaScript 1.7

function range(begin, end) { for (let i = begin; i < end; ++i) { yield i; }}

var ten_squares = [i * i for each (i in range(0, 10))];

var evens = [i for each (i in range(0, 21)) if (i % 2 == 0)];

Friday, November 9, 12

Page 23: Js in the open

let definitions

new in JavaScript 1.7

for (var i = 0; i < 10; i++) { console.log(i); // prints 0, 1, 2 ... 9}console.log(i); // prints 10

for (let i = 10; i < 100; i++) { console.log(i); // prints 10, 11, 12 ... 99}console.log(i); // prints 10

Friday, November 9, 12

Page 24: Js in the open

let definitions

new in JavaScript 1.7

function varTest() { var x = 31; if (true) { var x = 71; // same variable! alert(x); // 71 } alert(x); // 71}

function letTest() { let x = 31; if (true) { let x = 71; // different variable alert(x); // 71 } alert(x); // 31}

Friday, November 9, 12

Page 25: Js in the open

let statements and expressions

new in JavaScript 1.7

var x = 5;var y = 0; let (x = x + 10, y = 12) { console.log(x + y); // 15 + 12 = 27}console.log(x + y); // 5 + 0 = 5

var x = 5;var y = 0;console.log(let (x = x + 10, y = 12) x + y); // 15 + 12 = 27console.log(x + y); // 5 + 0 = 5

Friday, November 9, 12

Page 26: Js in the open

destructuring assignment

new in JavaScript 1.7

var array = [1, 2, 3];var [fir, sec, thi] = array; // fir = 1, sec = 2, thi = 3var [, x] = array; // x = 2

var obj = { name: "Jack Bauer", username: "JackB", id: 12345, agency: "CTU", region: "Los Angeles"};var [name, agency, region] = obj;// name = "Jack Bauer", agency = "CTU", region = "Los Angeles"

Friday, November 9, 12

Page 27: Js in the open

destructuring assignment

new in JavaScript 1.7

var a = 1;var b = 3; [a, b] = [b, a];

Friday, November 9, 12

Page 28: Js in the open

multiple value returns

new in JavaScript 1.7

function f() { return [1, 2];}

var [a, b] = f();console.log("A is " + a + " B is " + b);

Friday, November 9, 12

Page 29: Js in the open

multiple value returns

new in JavaScript 1.7

function f() { return { a: 1, b: 3 };}

var [a, b] = f();console.log("A is " + a + " B is " + b);

Friday, November 9, 12

Page 30: Js in the open

looping across objects

new in JavaScript 1.7

var obj = { name: "Jack Bauer", username: "JackB", id: 12345, agency: "CTU", region: "Los Angeles"}; obj.__iterator__ = function() { for (let item in this) { if (item != "id") { yield [item, this[item]]; } }};

for (let [item, value] in obj) { alert(item + ": " + value);}

Friday, November 9, 12

Page 31: Js in the open

2008

expression closures

getters and setters

generator expressions

more Array extras

new in JavaScript 1.8

Friday, November 9, 12

Page 32: Js in the open

expression closures

new in JavaScript 1.8

function(x) { return x * x; }// vs.function(x) x * x

var passed = [12, 5, 8, 130, 44].every(function(e) e >= 10);// passed is false

var passed = [12, 54, 18, 130, 44].every(function(e) e >= 10);// passed is true

Friday, November 9, 12

Page 33: Js in the open

expression closures

(short function syntax, strawman)

new in JavaScript 1.8

function(x) { return x * x; }// vs.ƒ(x) x * x

[12, 5, 8, 130, 44].map(ƒ(e) e / 2);// divide all values by 2

[12, 54, 18, 130, 44].map(ƒ(e) e % 2 ? true : false );// map odds and evens

Friday, November 9, 12

Page 34: Js in the open

getters and setters

new in JavaScript 1.8

var object = { _a: 7, get a() { return this._a + 1; }, set a(x) { this._a = x / 2; }};

Friday, November 9, 12

Page 35: Js in the open

getters and setters

new in JavaScript 1.8

var object = { _a: 7, get a() this._a + 1, set a(x) this._a = x / 2};

Friday, November 9, 12

Page 36: Js in the open

generator expressions

new in JavaScript 1.8

function add3(obj) { for (let i in obj) yield obj[i] + 3;}let it = add3([1, 2, 3]);

try { while (true) { alert(it.next()); }} catch (err if err instanceof StopIteration) { alert("End of record.");}

Friday, November 9, 12

Page 37: Js in the open

generator expressions

new in JavaScript 1.8

let it = (i + 3 for (i of [1, 2, 3]));

try { while (true) { alert(it.next()); }} catch (err if err instanceof StopIteration) { alert("End of record.");}

Friday, November 9, 12

Page 38: Js in the open

more Array extras

reduce(), reduceRight()

new in JavaScript 1.8

var total = [0, 1, 2, 3].reduce(function(a, b) { return a + b;});// total == 6

Friday, November 9, 12

Page 39: Js in the open

more Array extras

reduce(), reduceRight()

new in JavaScript 1.8

var total = [0, 1, 2, 3].reduce(function(a, b) a + b);

Friday, November 9, 12

Page 40: Js in the open

2009 ... ?

nicer Object API

default function params, rest params

for..of loops

WeakMaps, Maps, Sets

strict mode

ES5 to ES6 and beyond

Friday, November 9, 12

Page 41: Js in the open

Nicer Object APIvar obj1 = { name: "Jack Bauer", username: "JackB", id: 12345, agency: "CTU", region: "Los Angeles"}; var obj2 = Object.create(obj1, { foo: { value: "hello", writable: true, // value may be changed configurable: true // property may be changed or deleted }, bar: { enumerable: false, // shows up during enumeration get: function() { return 10 }, set: function(value) { alert("Setting 'o.bar' to", value); }});

Friday, November 9, 12

Page 42: Js in the open

Nicer Object API// Shape - classfunction Shape() { // Shape constructor this.x = 0; this.y = 0;}Shape.prototype.move = function() { this.x += 10; this.y += 10; console.info("Shape moved.");};

var shape = new Shape(); // instantiateshape.move(); // "Shape moved."

Friday, November 9, 12

Page 43: Js in the open

Nicer Object API// Shape - superclassfunction Shape() { // Shape constructor this.x = 0; this.y = 0;}Shape.prototype.move = function() { this.x += 10; this.y += 10; console.info("Shape moved.");};

// Rectangle - subclassfunction Rectangle() { // Rectangle constructor Shape.call(this); // call super constructor}Rectangle.prototype = Object.create(Shape.prototype); // inherit methodsRectangle.prototype.moveAt = function(x, y) { // define new methods this.x += x; this.y += y; console.info("Shape moved at: " + x + ", " + y);};

var rect = new Rectangle(); // instantiaterect instanceof Rectangle // truerect.move(); // "Shape moved."rect.moveAt(5, 2); // "Shape moved at: 5, 2"

Friday, November 9, 12

Page 44: Js in the open

Default and rest params

// when called, if no value or undefined is passed as second argument,// b will have 1 as value.function multiply(a, b = 1) { return a * b;}multiply(5); // 5

function fun(a, b, ...theArgs) { for (let arg of theArgs) console.log(arg);} fun(1, 2);fun(1, 2, 5); // logs 5fun(1, 2, 5, 6, 7); // logs 5, 6, 7

function sortRestArgs(x, ...someStuff) { return someStuff.sort();} console.log(sortRestArgs(0, 5, 3, 7, 1)); // logs 1, 3, 5, 7

Friday, November 9, 12

Page 45: Js in the open

for..of loops

let arr = [ 3, 5, 7 ];arr.foo = "hello"; for (let i in arr) { console.log(i); // logs "0", "1", "2", "foo"} for (let i of arr) { console.log(i); // logs "3", "5", "7"} for (let paragraph of document.querySelectorAll("article > p")) { paragraph.classList.add("read");}

Friday, November 9, 12

Page 46: Js in the open

Sets// Sets are collections in which values are unique.var mySet = new Set(); mySet.add(1);mySet.add(5);mySet.add("some text"); mySet.has(1); // truemySet.has(3); // false, 3 has not been added to the setmySet.has(5); // truemySet.has(Math.sqrt(25)); // truemySet.has("Some Text".toLowerCase()); // truemySet.size; // 3 mySet.delete(5); // removes 5 from the setmySet.has(5); // false, 5 has been removedmySet.size; // 2, we just removed one value // iterate over items in setfor (let item of mySet) console.log(item);// logs the items in the order: 1, "some text"

// convert set to plain Arrayvar myArr = [v for (v of mySet)]; // [1, "some text"]

Friday, November 9, 12

Page 47: Js in the open

Maps vs. Weak Maps// Maps are key/value collections in which keys are objects.var myMap = new Map(); // setting the valuesmyMap.set(keyString, "value associated with 'a string'");myMap.set(keyObj, "value associated with keyObj");myMap.set(keyFunc, "value associated with keyFunc"); myMap.size; // 3 // getting the valuesmyMap.get(keyString); // "value associated with 'a string'"myMap.get(keyObj); // "value associated with keyObj"myMap.get(keyFunc); // "value associated with keyFunc"myMap.get("a string"); // "value associated with 'a string'"

myMap.set(0, "positive zero");myMap.get(-0); // "negative zero"

myMap.set(-0, "negative zero");myMap.get(0); // "positive zero"

// iterate over items in mapfor (let [key, value] of mySet) console.log(value);

Friday, November 9, 12

Page 48: Js in the open

Strict mode"use strict";

mistypedVariable = 17; // throws a ReferenceError

delete Object.prototype;// throws a TypeError

var f = function() { return arguments.callee; };f(); // throws a TypeError

var o = { p: 1, p: 2 };// syntax error

function sum(a, a, c) { return a + a + c; }// syntax error

function that() { return this; }that(); // undefined

Friday, November 9, 12

Page 49: Js in the open

in a galaxy far far away ...

quasi-literals

thin and fat arrow functions with lexical this binding

triangle operator

modules

classes

ParallelArray

Harmony vs. Strawman

Friday, November 9, 12

Page 50: Js in the open

in a galaxy far far away ...

Paren-free

if year > 2010 { syntax++}

for i in iter { frob(i)}

while lo <= hi { let mid = (lo + hi) / 2}

... return [i * i for i in range(n)]

Friday, November 9, 12

Page 51: Js in the open

Rhino Unicorn

https://brendaneich.com/

Friday, November 9, 12

Page 52: Js in the open

https://brendaneich.com/

Friday, November 9, 12

Page 53: Js in the open

https://brendaneich.com/

Friday, November 9, 12

Page 54: Js in the open

Design patterns

Friday, November 9, 12

Page 55: Js in the open

We won’t talk about design patters

Friday, November 9, 12

Page 56: Js in the open

avoid defensive programming

premature optimization is evil

over-complicating things is eviler

over-engineering is the evilest

Friday, November 9, 12

Page 57: Js in the open

Friday, November 9, 12

Page 58: Js in the open

What we use at Mozilla

Friday, November 9, 12

Page 59: Js in the open

What we use at Mozilla

and you should too

Friday, November 9, 12

Page 60: Js in the open

OOP

MyNamespace.Fox = function() { this.name = ""; this.yearsOld = 0;};

MyNamespace.Fox.prototype = { run: function(param) { }, sleep: function() { }};

var pinky = new Fox();var leyla = new Fox();leyla.cuteness = 5;

Friday, November 9, 12

Page 61: Js in the open

MyNamespace.Fox = function(aName, aYearsOld) { this.name = aName; this.yearsOld = aYearsOld;};

MyNamespace.Fox.prototype = { run: function(param) { }, sleep: function() { }};

var pinky = new Fox("Pinky", 10);var leyla = new Fox("Leyla", 7);leyla.cuteness = 5;

OOP

constructors!

Friday, November 9, 12

Page 62: Js in the open

MyNamespace.Fox = function(aName, aYearsOld) { this.name = aName; this.yearsOld = aYearsOld;};

MyNamespace.Fox.prototype = { run: function(param) { }, sleep: function() { }};

var pinky = new Fox("Pinky", 10);var leyla = new Fox("Leyla", 7);leyla.cuteness = 5;

OOP

private members?

Friday, November 9, 12

Page 63: Js in the open

Closures!

function foo(a, b){ function bar() { return a + b; }

return bar();}

function foo2(a, b){ function bar(c) { return a + b + c; }

return bar;}

Friday, November 9, 12

Page 64: Js in the open

function foo(a, b){ function bar() { return a + b; }

return bar();}

function foo2(a, b){ function bar(c) { return a + b + c; }

return bar;}

Closures!

var res1 = foo(5, 2);

var res2 = foo2(5, 2);

var res3 = res2(3);

Friday, November 9, 12

Page 65: Js in the open

function foo(a, b){ function bar() { return a + b; }

return bar();}

function foo2(a, b){ function bar(c) { return a + b + c; }

return bar;}

Closures!

var res1 = foo(5, 2);// returns 7

var res2 = foo2(5, 2);// returns a closure function

var res3 = res2(3);// returns 7

Friday, November 9, 12

Page 66: Js in the open

MyNamespace.Fox = function(aName, aYearsOld) { this.name = aName; this.yearsOld = aYearsOld;};

MyNamespace.Fox.prototype = { run: function(param) { }, sleep: function() { }};

var pinky = new Fox("Pinky", 10);var leyla = new Fox("Leyla", 7);leyla.cuteness = 5;

leyla.yearsOld; // 7

OOP

private members?

Friday, November 9, 12

Page 67: Js in the open

MyNamespace.Fox = function(aName, aYearsOld) { this._name = aName; this._yearsOld = aYearsOld;};

MyNamespace.Fox.prototype = { run: function(param) { }, sleep: function() { }};

var pinky = new Fox("Pinky", 10);var leyla = new Fox("Leyla", 7);leyla.cuteness = 5;

leyla._yearsOld; // 7

OOP

we just _prefix them...and respect it

Friday, November 9, 12

Page 68: Js in the open

OOPMyNamespace.Fox = function(aName, aYearsOld) { var name = aName; var yearsOld = aYearsOld;

this.run = function(param) { }; this.sleep = function() { };};

var pinky = new Fox("Pinky", 10);var leyla = new Fox("Leyla", 7);leyla.cuteness = 5;

leyla.yearsOld; // undefined

you can have private members...if you really want to

Friday, November 9, 12

Page 69: Js in the open

OOPMyNamespace.Fox = function(aName, aYearsOld) { var name = aName; var yearsOld = aYearsOld;

this.run = function(param) { }; this.sleep = function() { }; Object.defineProperty(this, "yearsOld", { get: function() { return yearsOld * 6; } set: function(value) { yearsOld = value; } });};

var pinky = new Fox("Pinky", 10);var leyla = new Fox("Leyla", 7);leyla.cuteness = 5;

leyla.yearsOld; // 42

Friday, November 9, 12

Page 70: Js in the open

// Shape - superclassfunction Shape() { // Shape constructor this.x = 0; this.y = 0;}Shape.prototype.move = function() { this.x += 10; this.y += 10; console.info("Shape moved.");};

// Rectangle - subclassfunction Rectangle() { // Rectangle constructor Shape.call(this); // call super constructor}Rectangle.prototype = Object.create(Shape.prototype); // inherit methodsRectangle.prototype.moveAt = function(x, y) { // define new methods this.x += x; this.y += y; console.info("Shape moved at: " + x + ", " + y);};

var rect = new Rectangle(); // instantiaterect instanceof Rectangle // truerect.move(); // "Shape moved."rect.moveAt(5, 2); // "Shape moved at: 5, 2"

OOP

we generally take it easy :)

Friday, November 9, 12

Page 71: Js in the open

let observer = { observe: function(aSubject, aTopic, aData) { if (aTopic == "some-topic") { window.dump("Data received: " + aData); } } };

// observer for a notificationServices.obs.addObserver(observer, "some-topic", false);

// stop observingServices.obs.removeObserver(observer, "some-topic");

// somewhere, somebody does this:observerService.notifyObservers(someObject, "some-topic", "some-data");

Observers

Friday, November 9, 12

Page 72: Js in the open

XPCOMUtils.defineLazyGetter(myObject, "someProperty", function() { // do some heavy duty stuff // ... return something;});

// avoid disk activity, load modules only when neededXPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource:///modules/FileUtils.jsm");

Lazy getters

Friday, November 9, 12

Page 74: Js in the open

Debugging JavaScript in Firefox

(demo)

Friday, November 9, 12