Js in the open

  • 277 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
277
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
8
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

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