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

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.

Jean Carlo Emer

August 23, 2013
Tweet

More Decks by Jean Carlo Emer

Other Decks in Programming

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