Js in the open
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Js in the open

on

  • 516 views

 

Statistics

Views

Total Views
516
Views on SlideShare
513
Embed Views
3

Actions

Likes
0
Downloads
7
Comments
0

2 Embeds 3

http://www.linkedin.com 2
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Js in the open Presentation Transcript

  • 1. JS in the open (or JS in the wild)Friday, November 9, 12
  • 2. @victorporof Programmer at MozillaFriday, November 9, 12
  • 3. The JavaScript you probably knowFriday, November 9, 12
  • 4. Number String Boolean Object (Function, Array, Date, RegExp ...) Function Null UndefinedFriday, November 9, 12
  • 5. 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
  • 6. new Number(3) new String(“Gangnam Style”) new Boolean(false)Friday, November 9, 12
  • 7. typeof new Number(3) == “object” typeof new String(“Gangnam Style”) == “object” typeof new Boolean(false) == “object”Friday, November 9, 12
  • 8. typeof new Number(3) == “object” typeof new String(“Gangnam Style”) == “object” typeof new Boolean(false) == “object” ConstructorsFriday, November 9, 12
  • 9. JavaScript is fundamentally about ObjectsFriday, November 9, 12
  • 10. The JavaScript you probably don’t knowFriday, November 9, 12
  • 11. Friday, November 9, 12
  • 12. new in JavaScript 1.6 2006 Functional collectors Array extras Array and String generics for each..in loopsFriday, November 9, 12
  • 13. new in JavaScript 1.6 Functional collectors every(), filter(), forEach(), map(), some() 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 trueFriday, November 9, 12
  • 14. new in JavaScript 1.6 Functional collectors every(), filter(), forEach(), map(), some() 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
  • 15. new in JavaScript 1.6 Array extras indexOf(), lastIndexOf() var array = [2, 5, 9, 2]; var index = array.lastIndexOf(2); // index is 3 index = array.lastIndexOf(7); // index is -1 index = array.lastIndexOf(2, 3); // index is 3 index = array.lastIndexOf(2, 2); // index is 0 index = array.lastIndexOf(2, -1); // index is 3Friday, November 9, 12
  • 16. new in JavaScript 1.6 Array and String generics 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
  • 17. new in JavaScript 1.6 for each..in loops var sum = 0; var obj = { prop1: 5, prop2: 13, prop3: 8 }; for (var item in obj) { sum += item; } print(sum); // prints 0prop1prop2prop3Friday, November 9, 12
  • 18. new in JavaScript 1.6 for each..in loops 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+8Friday, November 9, 12
  • 19. new in JavaScript 1.7 2007 Generators Iterators Array comprehensions let statements, expressions, definitions destructuring assignment multiple value returns & looping across objectsFriday, November 9, 12
  • 20. new in JavaScript 1.7 Generators 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
  • 21. new in JavaScript 1.7 Iterators 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
  • 22. new in JavaScript 1.7 Array comprehensions 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
  • 23. new in JavaScript 1.7 let definitions 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 10Friday, November 9, 12
  • 24. new in JavaScript 1.7 let definitions 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
  • 25. new in JavaScript 1.7 let statements and expressions 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 = 27 console.log(x + y); // 5 + 0 = 5Friday, November 9, 12
  • 26. new in JavaScript 1.7 destructuring assignment var array = [1, 2, 3]; var [fir, sec, thi] = array; // fir = 1, sec = 2, thi = 3 var [, 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
  • 27. new in JavaScript 1.7 destructuring assignment var a = 1; var b = 3; [a, b] = [b, a];Friday, November 9, 12
  • 28. new in JavaScript 1.7 multiple value returns function f() { return [1, 2]; } var [a, b] = f(); console.log("A is " + a + " B is " + b);Friday, November 9, 12
  • 29. new in JavaScript 1.7 multiple value returns function f() { return { a: 1, b: 3 }; } var [a, b] = f(); console.log("A is " + a + " B is " + b);Friday, November 9, 12
  • 30. new in JavaScript 1.7 looping across objects 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
  • 31. new in JavaScript 1.8 2008 expression closures getters and setters generator expressions more Array extrasFriday, November 9, 12
  • 32. new in JavaScript 1.8 expression closures 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 trueFriday, November 9, 12
  • 33. new in JavaScript 1.8 expression closures (short function syntax, strawman) 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 evensFriday, November 9, 12
  • 34. new in JavaScript 1.8 getters and setters var object = { _a: 7, get a() { return this._a + 1; }, set a(x) { this._a = x / 2; } };Friday, November 9, 12
  • 35. new in JavaScript 1.8 getters and setters var object = { _a: 7, get a() this._a + 1, set a(x) this._a = x / 2 };Friday, November 9, 12
  • 36. new in JavaScript 1.8 generator expressions 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
  • 37. new in JavaScript 1.8 generator expressions 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
  • 38. new in JavaScript 1.8 more Array extras reduce(), reduceRight() var total = [0, 1, 2, 3].reduce(function(a, b) { return a + b; }); // total == 6Friday, November 9, 12
  • 39. new in JavaScript 1.8 more Array extras reduce(), reduceRight() var total = [0, 1, 2, 3].reduce(function(a, b) a + b);Friday, November 9, 12
  • 40. ES5 to ES6 and beyond 2009 ... ? nicer Object API default function params, rest params for..of loops WeakMaps, Maps, Sets strict modeFriday, November 9, 12
  • 41. Nicer Object API var 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
  • 42. Nicer Object API // Shape - class function 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(); // instantiate shape.move(); // "Shape moved."Friday, November 9, 12
  • 43. Nicer Object API // Shape - superclass function Shape() { // Shape constructor this.x = 0; this.y = 0; } Shape.prototype.move = function() { this.x += 10; this.y += 10; console.info("Shape moved."); }; // Rectangle - subclass function Rectangle() { // Rectangle constructor Shape.call(this); // call super constructor } Rectangle.prototype = Object.create(Shape.prototype); // inherit methods Rectangle.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(); // instantiate rect instanceof Rectangle // true rect.move(); // "Shape moved." rect.moveAt(5, 2); // "Shape moved at: 5, 2"Friday, November 9, 12
  • 44. 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 5 fun(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, 7Friday, November 9, 12
  • 45. 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
  • 46. 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); // true mySet.has(3); // false, 3 has not been added to the set mySet.has(5); // true mySet.has(Math.sqrt(25)); // true mySet.has("Some Text".toLowerCase()); // true mySet.size; // 3 mySet.delete(5); // removes 5 from the set mySet.has(5); // false, 5 has been removed mySet.size; // 2, we just removed one value // iterate over items in set for (let item of mySet) console.log(item); // logs the items in the order: 1, "some text" // convert set to plain Array var myArr = [v for (v of mySet)]; // [1, "some text"]Friday, November 9, 12
  • 47. Maps vs. Weak Maps // Maps are key/value collections in which keys are objects. var myMap = new Map(); // setting the values myMap.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 values myMap.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 map for (let [key, value] of mySet) console.log(value);Friday, November 9, 12
  • 48. 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(); // undefinedFriday, November 9, 12
  • 49. Harmony vs. Strawman in a galaxy far far away ... quasi-literals thin and fat arrow functions with lexical this binding triangle operator modules classes ParallelArrayFriday, November 9, 12
  • 50. Paren-free in a galaxy far far away ... 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
  • 51. Rhino Unicorn https://brendaneich.com/Friday, November 9, 12
  • 52. https://brendaneich.com/Friday, November 9, 12
  • 53. https://brendaneich.com/Friday, November 9, 12
  • 54. Design patternsFriday, November 9, 12
  • 55. We won’t talk about design pattersFriday, November 9, 12
  • 56. avoid defensive programming premature optimization is evil over-complicating things is eviler over-engineering is the evilestFriday, November 9, 12
  • 57. Friday, November 9, 12
  • 58. What we use at MozillaFriday, November 9, 12
  • 59. What we use at Mozilla and you should tooFriday, November 9, 12
  • 60. 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
  • 61. OOP MyNamespace.Fox = function(aName, aYearsOld) { this.name = aName; this.yearsOld = aYearsOld; }; MyNamespace.Fox.prototype = { constructors! run: function(param) { }, sleep: function() { } }; var pinky = new Fox("Pinky", 10); var leyla = new Fox("Leyla", 7); leyla.cuteness = 5;Friday, November 9, 12
  • 62. OOP MyNamespace.Fox = function(aName, aYearsOld) { this.name = aName; this.yearsOld = aYearsOld; }; MyNamespace.Fox.prototype = { private members? run: function(param) { }, sleep: function() { } }; var pinky = new Fox("Pinky", 10); var leyla = new Fox("Leyla", 7); leyla.cuteness = 5;Friday, November 9, 12
  • 63. 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
  • 64. Closures! function foo(a, b){ function bar() { return a + b; } var res1 = foo(5, 2); return bar(); } var res2 = foo2(5, 2); function foo2(a, b){ function bar(c) { var res3 = res2(3); return a + b + c; } return bar; }Friday, November 9, 12
  • 65. Closures! function foo(a, b){ function bar() { return a + b; } var res1 = foo(5, 2); return bar(); // returns 7 } var res2 = foo2(5, 2); // returns a closure function function foo2(a, b){ function bar(c) { var res3 = res2(3); return a + b + c; // returns 7 } return bar; }Friday, November 9, 12
  • 66. OOP MyNamespace.Fox = function(aName, aYearsOld) { this.name = aName; this.yearsOld = aYearsOld; }; MyNamespace.Fox.prototype = { run: function(param) { }, private members? sleep: function() { } }; var pinky = new Fox("Pinky", 10); var leyla = new Fox("Leyla", 7); leyla.cuteness = 5; leyla.yearsOld; // 7Friday, November 9, 12
  • 67. OOP MyNamespace.Fox = function(aName, aYearsOld) { this._name = aName; this._yearsOld = aYearsOld; }; MyNamespace.Fox.prototype = { run: function(param) { }, we just _prefix them sleep: function() { } ...and respect it }; var pinky = new Fox("Pinky", 10); var leyla = new Fox("Leyla", 7); leyla.cuteness = 5; leyla._yearsOld; // 7Friday, November 9, 12
  • 68. OOP MyNamespace.Fox = function(aName, aYearsOld) { var name = aName; var yearsOld = aYearsOld; this.run = function(param) { }; this.sleep = function() { }; you can have private members }; ...if you really want to var pinky = new Fox("Pinky", 10); var leyla = new Fox("Leyla", 7); leyla.cuteness = 5; leyla.yearsOld; // undefinedFriday, November 9, 12
  • 69. OOP MyNamespace.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; // 42Friday, November 9, 12
  • 70. OOP // Shape - superclass function Shape() { // Shape constructor this.x = 0; this.y = 0; } Shape.prototype.move = function() { this.x += 10; this.y += 10; console.info("Shape moved."); }; we generally take it easy :) // Rectangle - subclass function Rectangle() { // Rectangle constructor Shape.call(this); // call super constructor } Rectangle.prototype = Object.create(Shape.prototype); // inherit methods Rectangle.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(); // instantiate rect instanceof Rectangle // true rect.move(); // "Shape moved." rect.moveAt(5, 2); // "Shape moved at: 5, 2"Friday, November 9, 12
  • 71. Observers let observer = { observe: function(aSubject, aTopic, aData) { if (aTopic == "some-topic") { window.dump("Data received: " + aData); } } }; // observer for a notification Services.obs.addObserver(observer, "some-topic", false); // stop observing Services.obs.removeObserver(observer, "some-topic"); // somewhere, somebody does this: observerService.notifyObservers(someObject, "some-topic", "some-data");Friday, November 9, 12
  • 72. Lazy getters XPCOMUtils.defineLazyGetter(myObject, "someProperty", function() { // do some heavy duty stuff // ... return something; }); // avoid disk activity, load modules only when needed XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource:///modules/FileUtils.jsm");Friday, November 9, 12
  • 73. Debugger API + Scratchpad (demo) https://developer.mozilla.org/en-US/docs/Tools/Scratchpad https://wiki.mozilla.org/Debugger https://developer.mozilla.org/en-US/docs/JavaScriptFriday, November 9, 12
  • 74. Debugging JavaScript in Firefox (demo)Friday, November 9, 12