O fantástico mundo do JavaScript

O fantástico mundo do JavaScript

Apresentada no Brazil JS de 2013.

Você sabe os paradigmas e modelos que temos em mãos? O que mesmo é Javascript, sua razão de ser?

A saga de descobrimento de uma linguagem, suas características, dos objetos até módulos. E além disto, um pouco daquilo que está por vir com as novas especificações.

C5df370a883b65279af5a7ca94a5eed7?s=128

Jean Carlo Emer

August 23, 2013
Tweet

Transcript

  1. O fantástico mundo BrazilJS 2013 do JavaScript

  2. Buenas !

  3. Brendan Eich criador do JS

  4. Jean Carlo Emer [ 'github', 'speakerdeck', 'twitter' ].map(service => service

    + '.com/jcemer'; ); artesão da internet
  5. None
  6. None
  7. fantástico JavaScript é ?

  8. mil pessoas 21% do GitHub ubíqua

  9. Sobre a palestra • Paradigmas • Organização de código •

    Modularização • Novas funcionalidades da ES6
  10. paradigmas ! /Appl lement||window.HTM return!0;var a=document.createEl gment:"<script[^>]*>([\\S\\s]*?)</script\\s*>", i&&(Prototype.BrowserFeatures.SpecificElementExtensions=!1);v =null,c= n(c[0])&&(a=c.shift()),Object.extend(d,Class.Methods),d.superclass=a,d.subclasses=[],a&&

    );for(var e=0,f=c.length;f>e;e++)d.addMethods(c[e]);return d.prototype.initialize||(d.prototype.i s.superclass&&this.superclass.prototype,d=Object.keys(b);a&&(b.toString!=Object.prototype.toStri Of&&d.push("valueOf"));for(var e=0,f=d.length;f>e;e++){var g=d[e],h=b[g];if(c&&Object.isFunction apply(this,arguments)}}(g).wrap(i),h.valueOf=function(a){return function(){return a.valueOf.call( }this.prototype[g]=h}return this}var a=function(){for(var a in{toString:1})if("toString"===a)retu {switch(a){case null:return c;case void 0:return d}var b=typeof a;switch(b){case"boolean":return c]=b[c];return a}function t(a){try{return K(a)?"undefined":null===a?"null":a.inspect?a.inspect() ",{"":a},[])}function v(b,c,d){var e=c[b];r(e)===h&&"function"==typeof e.toJSON&&(e=e.toJSON(b)); rn"null";case!0:return"true";case!1:return"false"}var g=typeof e;switch(g){case"string":return e. ect":for(var i=0,n=d.length;n>i;i++)if(d[i]===e)throw new TypeError("Cyclic reference to '"+e+"' ar p=v(i,e,d);o.push("undefined"==typeof p?"null":p)}o="["+o.join(",")+"]"}else{for(var q=Object ct(!0)+":"+p)}o="{"+o.join(",")+"}"}return d.pop(),o}}function w(a){return JSON.stringify(a)}func ing.interpret(a)}function z(a){if(r(a)!==h)throw new TypeError;var c=[];for(var d in a)b.call(a, eturn c}function A(a){var b=[];for(var c in a)b.push(a[c]);return b}function B(a){return s({},a) ){return a instanceof Hash}function G(b){return a.call(b)===i}function H(b){return a.call(b)===l} ){return"undefined"==typeof a}var ,b=Object.prototype.hasOwnProperty,c="Null",d="Undefined",e="Boolean",f="Number",g="String",h="O ",m="[object Array]",n="[object Date]",o=window.JSON&&"function"==typeof JSON.stringify&&"0"===J ,p=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable" !1;return!0}(),E="function"==typeof Array.isArray&&Array.isArray([])&&!Array.isArray({});E&&(D=Ar ,keys:Object.keys||z,values:A,clone:B,isElement:C,isArray:D,isHash:F,isFunction:G,isString:H,isN ototype,function(){function b(a,b){for(var c=a.length,d=b.length;d--;)a[c+d]=b[d];return a}funct s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g,"").replace(/\ t.isUndefined(arguments[0]))return this;if(!Object.isFunction(this))throw new TypeError("The obj 1),g=function(){var a=c(f,arguments),d=b,d=this instanceof g?this:b;return e.apply(d,a)};return return function(a){var f=b([a||window.event],e);return d.apply(c,f)}}function g(){if(!arguments.l s);return b.apply(this,a)}}function h(b){var c=this,d=a.call(arguments,1);return b=1e3*b,window.s is.delay.apply(this,a)}function j(a){var c=this;return function(){var d=b([c.bind(this)],argumen is._methodized;var a=this;return this._methodized=function(){var c=b([this],arguments);return a. umentNames:d,bindAsEventListener:f,curry:g,delay:h,defer:i,wrap:j,methodize:k};return Function.p s.getUTCMonth() getUTCDate().toPaddedString(2)+"T"+this.getUTCHours().toPaddedString ISOString()}a.toISOString||(a.toISOString=b),a.toJSON| +?^=!:${}()|[\]\/\\])/g,"\\$1")};var Per terCallback:function(){th .timer),this
  11. • Orientação a objetos (através de prototype) • Funcional •

    Imperativo =[],a ubclasses.push(d)); d.prototype.initialize|| (d.prototype.initialize= {var c=this.superclass&& =Object.prototype.toStrin =Object.prototype.valueOf g=d[e],h=b[g];if(c&&Objec i=h;h=function(a){return (g).wrap(i),h.valueOf=func (i),h.toString=function(a) this.prototype[g]=h}return 1})if("toString"===a)return function(){function r(a){sw a;switch(b){case"boolean":r function s(a,b){for(var c i K(a)?"undefined":null===a?"n RangeError)return"...";throw e=c[b];r(e)===h&&"function"= k:case j:case l:e=e.valueOf( 1:return"false"}var g=typeof 0);case"number":return isFini ++)if(d[i]===e)throw new Type o=[];if(f===m){for(var i=0,n=e p?"null":p)}o="["+o.join(",")+ b=q[i],p=v(b,e,d);"undefined"! return d.pop(),o}}function w(a $H(a).toQueryString()}function function z(a){if(r(a)!==h)throw a)b.call(a,d)&&c.push(d);if(q)f A(a){var b=[];for(var c in a)b. {return!(!a||1!=a.nodeType)}func instanceof Hash}function G(b){re function I(b){return a.call(b)== {return"undefined"==typeof a}var a=Object.prototype.toString,b=Obj an",f="Number",g="String",h="Obj Number]",l="[objec Date]
  12. Valores são objetos! 'BrazilJS'.toUpperCase(); // BRAZILJS [1, 2, 3].slice(0, 2);

    // [1, 2] 2013.08.toFixed(); // '2013' (function (a, b) { return b }).call(null, 1, 2); // 2 ({property: 'value'}).hasOwnProperty('property'); // true
  13. • First-class functions Funções são como qualquer outro valor da

    linguagem var fn = function () { return 42 }; var object = { ! method: function () { ! ! return "content" ! } }; Funções
  14. • Higher-order functions Funções como argumentos ou valores de retorno

    var fn = function () { /* ... */ }; document.addEventListener('click', fn); !function () { ! return function () { /* ... */ }; }();
  15. É muito afude* ter objetos e funções de primeira classe

    ! * afude: legal
  16. /Appl lement||window.HTM return!0;var a=document.createEl gment:"<script[^>]*>([\\S\\s]*?)</script\\s*>", i&&(Prototype.BrowserFeatures.SpecificElementExtensions=!1);v =null,c= n(c[0])&&(a=c.shift()),Object.extend(d,Class.Methods),d.superclass=a,d.subclasses=[],a&& );for(var e=0,f=c.length;f>e;e++)d.addMethods(c[e]);return

    d.prototype.initialize||(d.prototype.i s.superclass&&this.superclass.prototype,d=Object.keys(b);a&&(b.toString!=Object.prototype.toStri Of&&d.push("valueOf"));for(var e=0,f=d.length;f>e;e++){var g=d[e],h=b[g];if(c&&Object.isFunction apply(this,arguments)}}(g).wrap(i),h.valueOf=function(a){return function(){return a.valueOf.call( }this.prototype[g]=h}return this}var a=function(){for(var a in{toString:1})if("toString"===a)retu {switch(a){case null:return c;case void 0:return d}var b=typeof a;switch(b){case"boolean":return c]=b[c];return a}function t(a){try{return K(a)?"undefined":null===a?"null":a.inspect?a.inspect() ",{"":a},[])}function v(b,c,d){var e=c[b];r(e)===h&&"function"==typeof e.toJSON&&(e=e.toJSON(b)); rn"null";case!0:return"true";case!1:return"false"}var g=typeof e;switch(g){case"string":return e. ect":for(var i=0,n=d.length;n>i;i++)if(d[i]===e)throw new TypeError("Cyclic reference to '"+e+"' ar p=v(i,e,d);o.push("undefined"==typeof p?"null":p)}o="["+o.join(",")+"]"}else{for(var q=Object ct(!0)+":"+p)}o="{"+o.join(",")+"}"}return d.pop(),o}}function w(a){return JSON.stringify(a)}func ing.interpret(a)}function z(a){if(r(a)!==h)throw new TypeError;var c=[];for(var d in a)b.call(a, eturn c}function A(a){var b=[];for(var c in a)b.push(a[c]);return b}function B(a){return s({},a) ){return a instanceof Hash}function G(b){return a.call(b)===i}function H(b){return a.call(b)===l} ){return"undefined"==typeof a}var ,b=Object.prototype.hasOwnProperty,c="Null",d="Undefined",e="Boolean",f="Number",g="String",h="O ",m="[object Array]",n="[object Date]",o=window.JSON&&"function"==typeof JSON.stringify&&"0"===J ,p=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable" !1;return!0}(),E="function"==typeof Array.isArray&&Array.isArray([])&&!Array.isArray({});E&&(D=Ar ,keys:Object.keys||z,values:A,clone:B,isElement:C,isArray:D,isHash:F,isFunction:G,isString:H,isN ototype,function(){function b(a,b){for(var c=a.length,d=b.length;d--;)a[c+d]=b[d];return a}funct s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g,"").replace(/\ t.isUndefined(arguments[0]))return this;if(!Object.isFunction(this))throw new TypeError("The obj 1),g=function(){var a=c(f,arguments),d=b,d=this instanceof g?this:b;return e.apply(d,a)};return return function(a){var f=b([a||window.event],e);return d.apply(c,f)}}function g(){if(!arguments.l s);return b.apply(this,a)}}function h(b){var c=this,d=a.call(arguments,1);return b=1e3*b,window.s is.delay.apply(this,a)}function j(a){var c=this;return function(){var d=b([c.bind(this)],argumen is._methodized;var a=this;return this._methodized=function(){var c=b([this],arguments);return a. umentNames:d,bindAsEventListener:f,curry:g,delay:h,defer:i,wrap:j,methodize:k};return Function.p s.getUTCMonth() getUTCDate().toPaddedString(2)+"T"+this.getUTCHours().toPaddedString ISOString()}a.toISOString||(a.toISOString=b),a.toJSON| +?^=!:${}()|[\]\/\\])/g,"\\$1")};var Per terCallback:function(){th .timer),this objetos {} orientação a
  17. Tipos primitivos 'BrazilJS'; true; 2013.08; The Secret Life of JavaScript

    Primitives http:/ /javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of- javascript-primitives undefined; null; new String('BrazilJS'); new Number(2013.08); new Boolean(true);
  18. Quase tudo é objeto ou pode ser convertido para automaticamente

    !
  19. new String('BrazilJS').toUpperCase(); new Array(1, 2, 3).slice(0, 2); new Number(2013.08).toFixed(); new

    Function('a', 'b', 'return b').call(null, 1, 2); String.prototype.toUpperCase; Array.prototype.slice; Number.prototype.toFixed; Function.prototype.call; Construtores nativos
  20. • Prefira notaçõs literais quando disponíveis. Nestes, esqueça o new

    'BrazilJS'; [1, 2, 3]; 2013.08; (function (a, b) { return b })(1, 2); • Não adicione propriedades ao prototype destes construtores Maintainable JavaScript: Don’t modify objects you don’t own http:/ /www.nczonline.net/blog/2010/03/02/maintainable-javascript- dont-modify-objects-you-down-own
  21. Object.prototype.var = 'foo'; for (var prop in {}) { !

    console.log(i, {}[prop]); } // log: var foo • A especificação pode evoluir e definir algum método que você já tenha declarado Avisei, não mexa!
  22. Object String 'BrazilJS' { current: 0 } Array [1, 2,

    3] ? ...
  23. Criando construtores function Counter() { this.current = 0; } var

    sample = new Counter(); sample.current; // 0 sample.constructor; // function Counter() { // this.current = 0 // }
  24. function Counter(min, max, current) { this.min = min || 0;

    this.max = max || 10e9; this.current = current || this.min; } Counter.prototype.next = function() { return this.current = Math.min(this.max, this.current + 1); }; Counter.prototype.isFirst = function() { return this.current <= this.min; };
  25. var sample = new Counter(0, 10); sample.isFirst(); // true sample.next();

    // 1 sample.isFirst(); // false function Counter(min, max, current) { this.min = min || 0 this.max = max || 10e9 this.current = current || this.min } Counter.prototype.next = function() { return this.current = Math.min(this.max, this.current + } Counter.prototype.isFirst = function() { return this.current <= this.min }
  26. Especializando alert(sample); [object Object] sample = new Counter(0, 10); sample.toString

    = function() { return this.current.toString(); }; alert(sample); 0 melhor retornar uma string thanks @fnando
  27. delete sample.toString; Counter.prototype.toString = function() { return this.current + '

    yeah'; }; alert(sample); 0 yeah
  28. Nosso primeiro construtor: função prototype, e new !

  29. S.O.L.I.D. • Single responsability principle • Open/closed principle Após implementado,

    o construtor não deve mais ser modificado. Um novo construtor deve ser criado reusando código através de herança
  30. Herança?! Deixa disto! O que você precisa mesmo é de

    composição
  31. 1 ~ Composição function Counter(min, max, current) { /* ...

    */ } function Spinner() { /* ... */ } function Carousel(itens) { this.counter = new Counter(0, itens.length) this.loading = new Spinner() }
  32. E se eu precisar de um construtor igual ao Counter

    mas com goToLast ?
  33. O fantástico mundo do CoffeeScript ->

  34. class Counter constructor: (@min = 0, @max = 10e9, @current)

    -> @current ?= @min next: -> @current = Math.min(@max, @current + 1) isFirst: -> @current <= @min class CounterPlus extends Counter goToLast: -> @current = @max CoffeeScript
  35. sample = new CounterPlus(0, 10) CoffeeScript sample.goToLast() # 10 sample.current

    # 10 class Counter constructor: (@min = 0, @max = 10e9, @cur @current ?= @min next: -> @current = Math.min(@max, @current + 1) isFirst: -> @current <= @min class CounterPlus extends Counter goToLast: -> @current = @max
  36. class Counter constructor: (@min = 0, @max = 10e9, @current)

    -> @current ?= @min next: -> @current = Math.min(@max, @current + 1) isFirst: -> @current <= @min class CounterPlus extends Counter goToLast: -> @current = @max CoffeeScript
  37. ES6 classes class Counter { constructor(min = 0, max =

    10e9, current = min) {} next() { return this.current = Math.min(this.max, this.current + 1) } isFirst() { return this.current <= this.min } } class CounterPlus extends Counter { goToLast() { this.current = this.max } }
  38. function Counter(min, max, current) { this.min = min || 0

    this.max = max || 10e9 this.current = current || this.min } Counter.prototype.next = function() { return this.current = Math.min(this.max, this.current + 1) } Counter.prototype.isFirst = function() { return this.current <= this.min } class CounterPlus extends Counter { goToLast() { this.current = this.max }
  39. function CounterPlus() { Counter.apply(this, arguments) } function InheritCounter() {} InheritCounter.prototype

    = Counter.prototype CounterPlus.prototype = new InheritCounter() CounterPlus.prototype.constructor = CounterPlus CounterPlus.prototype.goToLast = function() { return this.current = this.max } class CounterPlus extends Counter { goToLast() { this.current = this.max } } function Counter(min, max, current) { /* ... */ }
  40. function CounterPlus() { Counter.apply(this, arguments) } function InheritCounter() {} InheritCounter.prototype

    = Counter.prototype CounterPlus.prototype = new InheritCounter() CounterPlus.prototype.constructor = CounterPlus CounterPlus.prototype.goToLast = function() { return this.current = this.max } function Counter(min, max, current) { /* ... */ } class CounterPlus extends Counter { goToLast() { this.current = this.max } }
  41. function CounterPlus() { Counter.apply(this, arguments) } function InheritCounter() {} InheritCounter.prototype

    = Counter.prototype CounterPlus.prototype = new InheritCounter() CounterPlus.prototype.constructor = CounterPlus CounterPlus.prototype.goToLast = function() { return this.current = this.max } function Counter(min, max, current) { /* ... */ } class CounterPlus extends Counter { goToLast() { this.current = this.max } }
  42. function Counter(min, max, current) { /* ... */ } function

    CounterPlus() { Counter.apply(this, arguments) } function InheritCounter() {} InheritCounter.prototype = Counter.prototype CounterPlus.prototype = new InheritCounter() CounterPlus.prototype.constructor = CounterPlus CounterPlus.prototype.goToLast = function() { return this.current = this.max } 2 ~ Herança
  43. ES6 classes class Counter { /* ... */ } class

    CounterPlus extends Counter { goToLast() { this.current = this.max } }
  44. ES6 Class ~ Transpilers Comece a usar as classes do

    ES6 agora mesmo... em qualquer browser! Harmonizr https:/ /github.com/jdiamond/harmonizr ES6-Transpiler.js https:/ /github.com/termi/es6-transpiler Traceur Compiler https:/ /github.com/google/traceur-compiler
  45. 3 ~ Mixin var validateMixin = { ! validate: function

    () { /* ... */ } } var eventsMixin = { ! subscribe: function () { /* ... */ }, ! publish: function () { /* ... */ } } function Model() { ! /* ... */ } $.extend(Model.prototype, validateMixin, eventsMixin)
  46. Recapitulando técnicas • Composição Contendo outros construtores que implementam funcionalidades

    • Herança Via cadeia de prototype • Mixin Estendendo o prototype
  47. S.O.L.I.D. Open/closed principle Após implementado, o construtor não deve mais

    ser modificado. Um novo construtor deve ser criado reusando código através de herança The S.O.L.I.D. Object Oriented Programming(OOP) Principles http:/ /www.codeproject.com/Articles/60845/The-S-O-L-I-D-Object- Oriented-Programming-OOP-Prin
  48. /Appl lement||window.HTM return!0;var a=document.createEl gment:"<script[^>]*>([\\S\\s]*?)</script\\s*>", i&&(Prototype.BrowserFeatures.SpecificElementExtensions=!1);v =null,c= n(c[0])&&(a=c.shift()),Object.extend(d,Class.Methods),d.superclass=a,d.subclasses=[],a&& );for(var e=0,f=c.length;f>e;e++)d.addMethods(c[e]);return

    d.prototype.initialize||(d.prototype.i s.superclass&&this.superclass.prototype,d=Object.keys(b);a&&(b.toString!=Object.prototype.toStri Of&&d.push("valueOf"));for(var e=0,f=d.length;f>e;e++){var g=d[e],h=b[g];if(c&&Object.isFunction apply(this,arguments)}}(g).wrap(i),h.valueOf=function(a){return function(){return a.valueOf.call( }this.prototype[g]=h}return this}var a=function(){for(var a in{toString:1})if("toString"===a)retu {switch(a){case null:return c;case void 0:return d}var b=typeof a;switch(b){case"boolean":return c]=b[c];return a}function t(a){try{return K(a)?"undefined":null===a?"null":a.inspect?a.inspect() ",{"":a},[])}function v(b,c,d){var e=c[b];r(e)===h&&"function"==typeof e.toJSON&&(e=e.toJSON(b)); rn"null";case!0:return"true";case!1:return"false"}var g=typeof e;switch(g){case"string":return e. ect":for(var i=0,n=d.length;n>i;i++)if(d[i]===e)throw new TypeError("Cyclic reference to '"+e+"' ar p=v(i,e,d);o.push("undefined"==typeof p?"null":p)}o="["+o.join(",")+"]"}else{for(var q=Object ct(!0)+":"+p)}o="{"+o.join(",")+"}"}return d.pop(),o}}function w(a){return JSON.stringify(a)}func ing.interpret(a)}function z(a){if(r(a)!==h)throw new TypeError;var c=[];for(var d in a)b.call(a, eturn c}function A(a){var b=[];for(var c in a)b.push(a[c]);return b}function B(a){return s({},a) ){return a instanceof Hash}function G(b){return a.call(b)===i}function H(b){return a.call(b)===l} ){return"undefined"==typeof a}var ,b=Object.prototype.hasOwnProperty,c="Null",d="Undefined",e="Boolean",f="Number",g="String",h="O ",m="[object Array]",n="[object Date]",o=window.JSON&&"function"==typeof JSON.stringify&&"0"===J ,p=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable" !1;return!0}(),E="function"==typeof Array.isArray&&Array.isArray([])&&!Array.isArray({});E&&(D=Ar ,keys:Object.keys||z,values:A,clone:B,isElement:C,isArray:D,isHash:F,isFunction:G,isString:H,isN ototype,function(){function b(a,b){for(var c=a.length,d=b.length;d--;)a[c+d]=b[d];return a}funct s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g,"").replace(/\ t.isUndefined(arguments[0]))return this;if(!Object.isFunction(this))throw new TypeError("The obj 1),g=function(){var a=c(f,arguments),d=b,d=this instanceof g?this:b;return e.apply(d,a)};return return function(a){var f=b([a||window.event],e);return d.apply(c,f)}}function g(){if(!arguments.l s);return b.apply(this,a)}}function h(b){var c=this,d=a.call(arguments,1);return b=1e3*b,window.s is.delay.apply(this,a)}function j(a){var c=this;return function(){var d=b([c.bind(this)],argumen is._methodized;var a=this;return this._methodized=function(){var c=b([this],arguments);return a. umentNames:d,bindAsEventListener:f,curry:g,delay:h,defer:i,wrap:j,methodize:k};return Function.p s.getUTCMonth() getUTCDate().toPaddedString(2)+"T"+this.getUTCHours().toPaddedString ISOString()}a.toISOString||(a.toISOString=b),a.toJSON| +?^=!:${}()|[\]\/\\])/g,"\\$1")};var Per terCallback:function(){th .timer),this new Counter() VS { current: 0 }
  49. • Objetos literais não possibilitam o uso de herança, apenas

    composição e mixin • Objetos literais não compartilham código através do prototype
  50. • Objetos gerados por construtores podem ser mais rápidos ao

    acessar propriedades Teste no jsPerf http:/ /jsperf.com/property-access-object-literal-vs-constructor/3 V8: Fast property Access https:/ /developers.google.com/v8/design#prop_access via @askoth
  51. É poderoso: funções construtoras, new, call e de bônus o

    prototype !
  52. ]*>([\\ serFeatures.SpecificE ft()),Object.extend(d,Class.Methods),d.superclass =0,f=c.length;f>e;e++)d.addMethods(c[e]);return d.prototype.ini =this.superclass&&this.superclass.prototype,d=Object.keys(b);a&&(b.toString!=O t.prototype.valueOf&&d.push("valueOf"));for(var e=0,f=d.length;f>e;e++){var g=d[e],h=b[g];i unction(){return

    c[a].apply(this,arguments)}}(g).wrap(i),h.valueOf=function(a){return function() .toString.call(a)}}(i)}this.prototype[g]=h}return this}var a=function(){for(var a in{toString:1} unction(){function r(a){switch(a){case null:return c;case void 0:return d}var b=typeof a;switch(b a,b){for(var c in b)a[c]=b[c];return a}function t(a){try{return K(a)?"undefined":null===a?"null" nction u(a){return v("",{"":a},[])}function v(b,c,d){var e=c[b];r(e)===h&&"function"==typeof e.t itch(e){case null:return"null";case!0:return"true";case!1:return"false"}var g=typeof e;switch(g){ ring(e):"null";case"object":for(var i=0,n=d.length;n>i;i++)if(d[i]===e)throw new TypeError("Cycli ,n=e.length;n>i;i++){var p=v(i,e,d);o.push("undefined"==typeof p?"null":p)}o="["+o.join(",")+"]" peof p&&o.push(b.inspect(!0)+":"+p)}o="{"+o.join(",")+"}"}return d.pop(),o}}function w(a){return a.toHTML?a.toHTML():String.interpret(a)}function z(a){if(r(a)!==h)throw new TypeError;var c=[];fo .call(a,d)&&c.push(d);return c}function A(a){var b=[];for(var c in a)b.push(a[c]);return b}functi ll(b)===m}function F(a){return a instanceof Hash}function G(b){return a.call(b)===i}function H(b ll(b)===n}function K(a){return"undefined"==typeof a}var ject.prototype.toString,b=Object.prototype.hasOwnProperty,c="Null",d="Undefined",e="Boolean",f="N r]",l="[object String]",m="[object Array]",n="[object Date]",o=window.JSON&&"function"==typeof J stringify(Prototype.K),p=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf" ("toString"===a)return!1;return!0}(),E="function"==typeof Array.isArray&&Array.isArray([])&&!Arra oQueryString:x,toHTML:y,keys:Object.keys||z,values:A,clone:B,isElement:C,isArray:D,isHash:F,isFun ect.extend(Function.prototype,function(){function b(a,b){for(var c=a.length,d=b.length;d--;)a[c+ .toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n]) guments.length<2&&Object.isUndefined(arguments[0]))return this;if(!Object.isFunction(this))throw his,f=a.call(arguments,1),g=function(){var a=c(f,arguments),d=b,d=this instanceof g?this:b;return e=a.call(arguments,1);return function(a){var f=b([a||window.event],e);return d.apply(c,f)}}funct n(){var a=c(d,arguments);return b.apply(this,a)}}function h(b){var c=this,d=a.call(arguments,1); 1],arguments);return this.delay.apply(this,a)}function j(a){var c=this;return function(){var d=b( ._methodized)return this._methodized;var a=this;return this._methodized=function(){var c=b([this prototype.slice,l={argumentNames:d,bindAsEventListener:f,curry:g,delay:h,defer:i,wrap:j,methodiz UTCFullYear()+"-"+(this.getUTCMonth() ddedString(2)+"-"+this.getUTCDate().toPaddedString(2)+"T"+this.getUTCHours().toPaddedString(2)+": ion c(){return this.toISOString()}a.toISOString||(a.toISOString=b),a.toJSON||(a.toJSON=c)}(Da tring(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")};var PeriodicalExecuter=C gisterCallback()},registerCallback:function(){this.timer=setInterv er&&(clearInterval(this.timer),this.timer=null)},onT hrow this.currentlyExecuting=!1,a}}}) \\\\"}}),Object.extend( sub(a,b){ funcional ->
  53. Coleções var data = [1, 2, 3, 4, 5, 6]

    , result = [] , i = 0 , item = null while (i < data.length) { item = data[i] result.push(item * 2) i++ } // result = [2, 4, 6, 8, 10, 12]
  54. Arrays extras • Métodos para manipular arrays vindos da especificação

    do ES5
  55. var data = [1, 2, 3, 4, 5, 6] ,

    result result = data.map(function (item) { return item * 2 }) // result = [2, 4, 6, 8, 10, 12] // data = [1, 2, 3, 4, 5, 6]
  56. var data = [1, 2, 3, 4, 5, 6] ,

    result result = data.reduce(function (sum, item) { return sum + item }, 0) // TRACE: // 0 + 1 // (0 + 1) + 2 // (0 + 1 + 2) + 3 // (0 + 1 + 2 + 3) + 4 // (0 + 1 + 2 + 3 + 4) + 5 // (0 + 1 + 2 + 3 + 4 + 5) + 6 // result = 21 // data = [1, 2, 3, 4, 5, 6]
  57. Manipulando arrays Array.prototype.forEach Array.prototype.every Array.prototype.some Array.prototype.filter Array.prototype.map Array.prototype.reduce Array.prototype.reduceRight Implementado

    em ie9+ http:/ /kangax.github.io/es5-compat-table ES5-shim https:/ /github.com/kriskowal/es5-shim
  58. Bibliotecas funcionais • O JavaScript não possui muitas funções para

    uso geral • Apenas arrays podem ser manipulados por funções como se fossem coleções
  59. jQuery var data = { what: 'BrazilJS', where: 'POA' }

    $.map(data, function (item) { return item }) // ['BrazilJS', 'POA'] var data = { what: 'BrazilJS', where: 'POA' } $.each(data, function (item) { console.log(item) }) // log: what // log: where
  60. Underscore _.map({ what: 'BrazilJS', city: 'POA' }, _.identity) // ['BrazilJS',

    'POA'] _.flatten([1, [2], [3, [[4]]]]); // [1, 2, 3, 4]; _.groupBy([1.3, 2.1, 2.4], function (num) { return Math.floor(num) }) // {1: [1.3], 2: [2.1, 2.4]}
  61. Bilby.js Modelagem Categorial do Programa Google Talk https:/ /speakerdeck.com/jcemer/modelagem-categorial-do-programa- google-talk

    • Aplica Teoria das Categorias...
  62. Bilby.js Modelagem Categorial do Programa Google Talk https:/ /speakerdeck.com/jcemer/modelagem-categorial-do-programa- google-talk

    • Aplica Teoria das Categorias... Functional JavaScript Michael Fogus http:/ /shop.oreilly.com/product/0636920028857.do
  63. /Appl lement||window.HTM return!0;var a=document.createEl gment:"<script[^>]*>([\\S\\s]*?)</script\\s*>", i&&(Prototype.BrowserFeatures.SpecificElementExtensions=!1);v =null,c= n(c[0])&&(a=c.shift()),Object.extend(d,Class.Methods),d.superclass=a,d.subclasses=[],a&& );for(var e=0,f=c.length;f>e;e++)d.addMethods(c[e]);return

    d.prototype.initialize||(d.prototype.i s.superclass&&this.superclass.prototype,d=Object.keys(b);a&&(b.toString!=Object.prototype.toStri Of&&d.push("valueOf"));for(var e=0,f=d.length;f>e;e++){var g=d[e],h=b[g];if(c&&Object.isFunction apply(this,arguments)}}(g).wrap(i),h.valueOf=function(a){return function(){return a.valueOf.call( }this.prototype[g]=h}return this}var a=function(){for(var a in{toString:1})if("toString"===a)retu {switch(a){case null:return c;case void 0:return d}var b=typeof a;switch(b){case"boolean":return c]=b[c];return a}function t(a){try{return K(a)?"undefined":null===a?"null":a.inspect?a.inspect() ",{"":a},[])}function v(b,c,d){var e=c[b];r(e)===h&&"function"==typeof e.toJSON&&(e=e.toJSON(b)); rn"null";case!0:return"true";case!1:return"false"}var g=typeof e;switch(g){case"string":return e. ect":for(var i=0,n=d.length;n>i;i++)if(d[i]===e)throw new TypeError("Cyclic reference to '"+e+"' ar p=v(i,e,d);o.push("undefined"==typeof p?"null":p)}o="["+o.join(",")+"]"}else{for(var q=Object ct(!0)+":"+p)}o="{"+o.join(",")+"}"}return d.pop(),o}}function w(a){return JSON.stringify(a)}func ing.interpret(a)}function z(a){if(r(a)!==h)throw new TypeError;var c=[];for(var d in a)b.call(a, eturn c}function A(a){var b=[];for(var c in a)b.push(a[c]);return b}function B(a){return s({},a) ){return a instanceof Hash}function G(b){return a.call(b)===i}function H(b){return a.call(b)===l} ){return"undefined"==typeof a}var ,b=Object.prototype.hasOwnProperty,c="Null",d="Undefined",e="Boolean",f="Number",g="String",h="O ",m="[object Array]",n="[object Date]",o=window.JSON&&"function"==typeof JSON.stringify&&"0"===J ,p=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable" !1;return!0}(),E="function"==typeof Array.isArray&&Array.isArray([])&&!Array.isArray({});E&&(D=Ar ,keys:Object.keys||z,values:A,clone:B,isElement:C,isArray:D,isHash:F,isFunction:G,isString:H,isN ototype,function(){function b(a,b){for(var c=a.length,d=b.length;d--;)a[c+d]=b[d];return a}funct s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g,"").replace(/\ t.isUndefined(arguments[0]))return this;if(!Object.isFunction(this))throw new TypeError("The obj 1),g=function(){var a=c(f,arguments),d=b,d=this instanceof g?this:b;return e.apply(d,a)};return return function(a){var f=b([a||window.event],e);return d.apply(c,f)}}function g(){if(!arguments.l s);return b.apply(this,a)}}function h(b){var c=this,d=a.call(arguments,1);return b=1e3*b,window.s is.delay.apply(this,a)}function j(a){var c=this;return function(){var d=b([c.bind(this)],argumen is._methodized;var a=this;return this._methodized=function(){var c=b([this],arguments);return a. umentNames:d,bindAsEventListener:f,curry:g,delay:h,defer:i,wrap:j,methodize:k};return Function.p s.getUTCMonth() getUTCDate().toPaddedString(2)+"T"+this.getUTCHours().toPaddedString ISOString()}a.toISOString||(a.toISOString=b),a.toJSON| +?^=!:${}()|[\]\/\\])/g,"\\$1")};var Per terCallback:function(){th .timer),this VS orientação a objetos funcional
  64. Um paradigma não exclui o outro! • Orientação a objetos

    Comportamento e estado • Funcional Computação baseada em transformação dos dados
  65. Como mantenho informações privadas em meu código ?

  66. None
  67. Eu não escondo com frequência. Mas quando o faço, usar

    closure é a única opção Michael Fogus
  68. Closure?! • Função que captura variáveis do escopo em que

    é definida var counter = (function(){ var current = 0 return function closure () { return current++ } })()
  69. function counterClosure(min, max, current) { min = min || 0

    max = max || 10e9 current = current || min return { next: function () { return current = Math.min(max, current + 1) }, isFirst: function () { return current <= min } } } var counter = counterClosure()
  70. Ok, agora tenho meu código privado !

  71. [...], the browser remains an inherently insecure execution environment; no

    amount of JavaScript trickery can fix that. If you are writing client-side code that needs to be trusted, my advice is to off-load sensitive operations to a secure server. Information Hiding in JavaScript Mike Pennisi
  72. [...], o browser continua um ambiente de execução inseguro; artimanhas

    no JavaScript não podem corrigir isto. Se você está codando algo que precise ser confiável, meu aviso é que operações sensíveis devam ser reservadas a um servidor seguro. Information Hiding in JavaScript Mike Pennisi
  73. Closure Pattern The access protection provided by this closure pattern

    is a powerful technique available to JavaScript programmers for keeping sanity in the face of software complexity. Functional JavaScript Michael Fogus
  74. Closure Pattern A restrição de acesso proporcionada pelo closure pattern

    é uma técnica poderosa, que pode ajudar desenvolvedores JavaScript a manter o nível de complexidade do software sob controle. Functional JavaScript Michael Fogus
  75. >([\\ erFeatures.Specific t()),Object.extend(d,Class.Methods),d.superclas ,f=c.length;f>e;e++)d.addMethods(c[e]);return d.prototype.ini his.superclass&&this.superclass.prototype,d=Object.keys(b);a&&(b.toString!= .prototype.valueOf&&d.push("valueOf"));for(var e=0,f=d.length;f>e;e++){var g=d[e],h=b[g]; function(){return

    c[a].apply(this,arguments)}}(g).wrap(i),h.valueOf=function(a){return function() a.toString.call(a)}}(i)}this.prototype[g]=h}return this}var a=function(){for(var a in{toString:1} unction(){function r(a){switch(a){case null:return c;case void 0:return d}var b=typeof a;switch( (a,b){for(var c in b)a[c]=b[c];return a}function t(a){try{return K(a)?"undefined":null===a?"null unction u(a){return v("",{"":a},[])}function v(b,c,d){var e=c[b];r(e)===h&&"function"==typeof e.t witch(e){case null:return"null";case!0:return"true";case!1:return"false"}var g=typeof e;switch(g) ring(e):"null";case"object":for(var i=0,n=d.length;n>i;i++)if(d[i]===e)throw new TypeError("Cycl 0,n=e.length;n>i;i++){var p=v(i,e,d);o.push("undefined"==typeof p?"null":p)}o="["+o.join(",")+"] ypeof p&&o.push(b.inspect(!0)+":"+p)}o="{"+o.join(",")+"}"}return d.pop(),o}}function w(a){return a.toHTML?a.toHTML():String.interpret(a)}function z(a){if(r(a)!==h)throw new TypeError;var c=[];f .call(a,d)&&c.push(d);return c}function A(a){var b=[];for(var c in a)b.push(a[c]);return b}funct all(b)===m}function F(a){return a instanceof Hash}function G(b){return a.call(b)===i}function H(b all(b)===n}function K(a){return"undefined"==typeof a}var ject.prototype.toString,b=Object.prototype.hasOwnProperty,c="Null",d="Undefined",e="Boolean",f=" er]",l="[object String]",m="[object Array]",n="[object Date]",o=window.JSON&&"function"==typeof .stringify(Prototype.K),p=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf" f("toString"===a)return!1;return!0}(),E="function"==typeof Array.isArray&&Array.isArray([])&&!Arr oQueryString:x,toHTML:y,keys:Object.keys||z,values:A,clone:B,isElement:C,isArray:D,isHash:F,isFu ject.extend(Function.prototype,function(){function b(a,b){for(var c=a.length,d=b.length;d--;)a[c s.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n]) guments.length<2&&Object.isUndefined(arguments[0]))return this;if(!Object.isFunction(this))throw his,f=a.call(arguments,1),g=function(){var a=c(f,arguments),d=b,d=this instanceof g?this:b;retur ,e=a.call(arguments,1);return function(a){var f=b([a||window.event],e);return d.apply(c,f)}}func on(){var a=c(d,arguments);return b.apply(this,a)}}function h(b){var c=this,d=a.call(arguments,1); 1],arguments);return this.delay.apply(this,a)}function j(a){var c=this;return function(){var d=b s._methodized)return this._methodized;var a=this;return this._methodized=function(){var c=b([thi .prototype.slice,l={argumentNames:d,bindAsEventListener:f,curry:g,delay:h,defer:i,wrap:j,methodiz tUTCFullYear()+"-"+(this.getUTCMonth() ddedString(2)+"-"+this.getUTCDate().toPaddedString(2)+"T"+this.getUTCHours().toPaddedString(2)+" tion c(){return this.toISOString()}a.toISOString||(a.toISOString=b),a.toJSON||(a.toJSON=c)}(Date String(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")};var PeriodicalExecuter=Cla gisterCallback()},registerCallback:function(){this.timer=setInterva er&&(clearInterval(this.timer),this.timer=null)},onTi throw this.currentlyExecuting=!1,a}}}); "\\\\"}}),Object.extend(St sub(a,b){va módulos ( )
  76. • Peças isoladas que podem ser adicionadas e removidas quando

    necessário • Devem poder indicar demais peças que constituem dependência
  77. Module Pattern via namespace var namespace = {} namespace.Util =

    (function () { /* ... */ })() namespace.Data = (function () { var util = namespace.Util , data = {} return { set: function (el, key, value) { /* ... */ } , get: function (el, key) { /* ... */} } })()
  78. Rye.define('Data', function () { var util = Rye.require('Util') , data

    = {} function set (element, key, value) { /* ... */ } function get (element, key) { /* ... */} return { set: set , get: get } }) Rye Modules Revealing Module Pattern Rye http:/ /ryejs.com
  79. AMD Asyncronous Module Definition define(['util'], function (util) { var data

    = {} function set (element, key, value) { /* ... */ } function get (element, key) { /* ... */} return { set: set , get: get } })
  80. AMD Asyncronous Module Definition Require.js http:/ /requirejs.org AMD is better

    for the web than CommonJS modules http:/ /blog.millermedeiros.com/amd-is-better-for-the-web-than- commonjs-modules • Assíncrono por natureza e funciona nos browsers atuais • Necessita de um loader como o require.js
  81. CJS CommonJS module var util = require('util') , data =

    {} function set (element, key, value) { /* ... */ } function get (element, key) { /* ... */} exports = { set: set , get: get }
  82. • Não compatível com browsers Pode ser levado ao browser

    através de ferramentas como browserify Browserify http:/ /browserify.org Asynchronous Module Loading With Browserify http:/ /esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module- loading-with-browserify CJS CommonJS module
  83. ES6 modules

  84. ES6 Modules module util from "util" let data = {}

    export function set () { /* ... */ } export function get () { /* ... */ } Module Spec http:/ /wiki.ecmascript.org/doku.php?id=harmony:modules Module loaders Spec http:/ /wiki.ecmascript.org/doku.php?id=harmony:module_loaders ES6 modules
  85. ES6 Modules ~ Transpilers Comece a usar os módulos do

    ES6 agora mesmo... em qualquer browser! Harmonizr (desatualizado) https:/ /github.com/jdiamond/harmonizr Esprima ~ ES6 parser https:/ /github.com/ariya/esprima/tree/harmony ES6 Module Loader https:/ /github.com/ModuleLoader/es6-module-loader ES6 modules
  86. JSPM module loader • Suporta ES6, AMD e CJS •

    Utiliza o protocolo SPDY JSPM http:/ /jspm.io SPDY http:/ /en.wikipedia.org/wiki/SPDY
  87. E muito mais... • let & const As novas vars

    • Set Bem vinda teoria dos conjuntos Spec da ES6 http:/ /wiki.ecmascript.org/doku.php?id=harmony:proposals ES6 Compatibility table http:/ /kangax.github.io/es5-compat-table/es6 ES6 stuffs
  88. E muito mais... • Iterators & Generators Evoluíndo o conceito

    de coleções e controlando fluxo do código ES6 stuffs Spec da ES6 http:/ /wiki.ecmascript.org/doku.php?id=harmony:proposals ES6 Compatibility table http:/ /kangax.github.io/es5-compat-table/es6
  89. Perguntas ? @jcemer

  90. Setas, setas, setas, setas, setas!!!! Loop Infinito - ECMAScript 6

    Arrow Function http:/ /loopinfinito.com.br/2013/08/20/ecmascript-6-arrow-function Callable entities in ECMAScript 6 http:/ /www.2ality.com/2013/08/es6-callables.html ES6 arrows [ 'github', 'speakerdeck', 'twitter' ].map (service => service + '.com/jcemer' )
  91. fantástico JavaScript é ?

  92. Obrigado ! @jcemer