JavaScript Transformation - JSConf 2015

JavaScript Transformation - JSConf 2015

9b7cbca4917f83679696b0924d0ed09d?s=128

sebmck

May 31, 2015
Tweet

Transcript

  1. 5.
  2. 6.
  3. 7.
  4. 8.
  5. 9.
  6. 10.
  7. 11.
  8. 12.
  9. 14.

    { type: "Program", body: [{ type: "VariableDeclaration" kind: "var", declarations:

    [{ type: "VariableDeclarator", id: { type: "Identifier", name: "foo" }, init: { type: “FunctionExpression", id: { type: “Identifier”, name: “foo” }, params: [], body: [{ type: "BlockStatement", body: [{ type: "ReturnStatement", argument: { type: "Identifier", name: "bar" } }] }] } }] }] } AST
  10. 18.

    Function Declaration Block Statement Return Statement Program Variable Declaration Variable

    Declarator Identifier Function Expression Block Statement Return Statement Identifier Traversal Visitor
  11. 27.

    Uses • Transpilation • Application optimisation • Browser compatibility •

    Minification • Obfuscation • Hot reloading • Code coverage • Language experimentation • Conditional compilation • Dynamic polyfill inclusion • Module mocking • Code linting • Execution tracing • Intellisense • Profiling • Refactoring • Dependency analysis • Instrumentation • Module bundling • …
  12. 29.
  13. 30.
  14. 31.

    • Additional standard lib methods • Arrow functions • Block

    scoping • Classes • Collections • Computed properties • Constants • Destructuring • Default and rest parameters • Generators • Iterators and for…of • Modules • Promises • Property method and value shorthand • Proxies • Spread • Sticky and unicode regexes • Symbols • Subclassable built-ins • Template literals • Better unicode support • Binary and octal literals • Reflect API • Tail calls
  15. 32.
  16. 33.
  17. 35.

    ES2015 Arrow Functions • Implicit return for expression bodies •

    “Inherits” arguments and this binding • Cannot new it • No prototype
  18. 36.

    Implicit return for expression bodies var multiple = (num) =>

    num * num; // turns into var multiply = function (num) { return num * num; };
  19. 37.

    ES2015 Arrow Functions • Implicit return for expression bodies •

    “Inherits” arguments and this binding • Cannot new it • No prototype ✓
  20. 38.

    arguments and this var bob = { name: “Bob” friends:

    [“Amy”], printFriends() { this.friends.forEach(f => console.log(this.name + " knows " + f) ); } };
  21. 39.

    arguments and this var bob = { name: “Bob”, friends:

    [“Amy”], printFriends() { var _this = this; this.friends.forEach(function (f) { return console.log(_this.name + " knows " + f); }); } };
  22. 40.

    ES2015 Arrow Functions • Implicit return for expression bodies •

    “Inherits” arguments and this binding • Cannot new it • No prototype ✓ ✓
  23. 41.

    no new var foo = () => {}; new foo;

    // should be illegal!
  24. 42.

    no new function _construct(obj) { if (obj.name === “_arrow”) throw

    new Error(“nope”); return new obj; } var foo = function _arrow() {}; _construct(foo);
  25. 43.

    no new function _construct(obj) { if (obj._arrow === “_arrow”) throw

    new Error(“nope”); return new obj; } var foo = function () {}; foo._arrow = true; _construct(foo);
  26. 44.
  27. 45.

    • Implicit return for expression bodies • “Inherits” arguments and

    this binding • Cannot new it • No prototype ✗ ES2015 Arrow Functions ✓ ✓
  28. 47.

    no prototype function _getPrototype(obj) { if (obj._arrow) { return undefined;

    } else { return obj.prototype; } } var foo = function () {}; foo._arrow = true; _getPrototype(foo);
  29. 49.

    no prototype function get(obj, key) { if (key === “prototype”)

    { return obj._arrow ? undefined : obj.prototype; } else { return obj[key]; } } var bar = “prototype”; var foo = () => {}; get(foo, bar);
  30. 50.
  31. 51.
  32. 53.
  33. 55.
  34. 59.

    JSX Constant Elements var Foo = require(“Foo”); function createComponent(text) {

    return function render() { return <Foo>{text}</Foo>; }; }
  35. 60.

    JSX Constant Elements var Foo = require(“Foo”); function createComponent(text) {

    var foo = <Foo>{text}</Foo>; return function render() { return foo; }; }
  36. 61.
  37. 63.

    import hbs from “htmlbars-inline-precompile"; var a = Ember.HTMLBars.template(function() { /*

    crazy HTMLBars template function stuff */ }); Precompiling tagged templates
  38. 64.

    • Shouldn’t rely on preprocessing for functionality • YOU can

    make assumptions about your code • JS engine can’t be more lenient
  39. 65.
  40. 66.
  41. 67.

    Named function expressions var f = function g() {}; typeof

    g === “function”; // true f === g; // false https://kangax.github.io/nfe/#jscript-bugs
  42. 69.

    export function FunctionExpression(node, print) { if (!node.id) return; return t.callExpression(

    t.functionExpression(null, [], t.blockStatement([ t.toStatement(node), t.returnStatement(node.id) ])), [] ); } Automate it!
  43. 70.

    Result var f = function g() {}; // becomes var

    f = (function () { function g() {} return g; })();
  44. 73.
  45. 74.
  46. 75.
  47. 78.