Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScript Transformation - JSConf 2015

JavaScript Transformation - JSConf 2015

sebmck

May 31, 2015
Tweet

More Decks by sebmck

Other Decks in Programming

Transcript

  1. { 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
  2. Function Declaration Block Statement Return Statement Program Variable Declaration Variable

    Declarator Identifier Function Expression Block Statement Return Statement Identifier Traversal Visitor
  3. 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 • …
  4. • 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
  5. ES2015 Arrow Functions • Implicit return for expression bodies •

    “Inherits” arguments and this binding • Cannot new it • No prototype
  6. Implicit return for expression bodies var multiple = (num) =>

    num * num; // turns into var multiply = function (num) { return num * num; };
  7. ES2015 Arrow Functions • Implicit return for expression bodies •

    “Inherits” arguments and this binding • Cannot new it • No prototype ✓
  8. arguments and this var bob = { name: “Bob” friends:

    [“Amy”], printFriends() { this.friends.forEach(f => console.log(this.name + " knows " + f) ); } };
  9. 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); }); } };
  10. ES2015 Arrow Functions • Implicit return for expression bodies •

    “Inherits” arguments and this binding • Cannot new it • No prototype ✓ ✓
  11. no new var foo = () => {}; new foo;

    // should be illegal!
  12. no new function _construct(obj) { if (obj.name === “_arrow”) throw

    new Error(“nope”); return new obj; } var foo = function _arrow() {}; _construct(foo);
  13. no new function _construct(obj) { if (obj._arrow === “_arrow”) throw

    new Error(“nope”); return new obj; } var foo = function () {}; foo._arrow = true; _construct(foo);
  14. • Implicit return for expression bodies • “Inherits” arguments and

    this binding • Cannot new it • No prototype ✗ ES2015 Arrow Functions ✓ ✓
  15. no prototype function _getPrototype(obj) { if (obj._arrow) { return undefined;

    } else { return obj.prototype; } } var foo = function () {}; foo._arrow = true; _getPrototype(foo);
  16. 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);
  17. JSX Constant Elements var Foo = require(“Foo”); function createComponent(text) {

    return function render() { return <Foo>{text}</Foo>; }; }
  18. JSX Constant Elements var Foo = require(“Foo”); function createComponent(text) {

    var foo = <Foo>{text}</Foo>; return function render() { return foo; }; }
  19. import hbs from “htmlbars-inline-precompile"; var a = Ember.HTMLBars.template(function() { /*

    crazy HTMLBars template function stuff */ }); Precompiling tagged templates
  20. • Shouldn’t rely on preprocessing for functionality • YOU can

    make assumptions about your code • JS engine can’t be more lenient
  21. Named function expressions var f = function g() {}; typeof

    g === “function”; // true f === g; // false https://kangax.github.io/nfe/#jscript-bugs
  22. 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!
  23. Result var f = function g() {}; // becomes var

    f = (function () { function g() {} return g; })();