Slide 1

Slide 1 text

O fantástico mundo BrazilJS 2013 do JavaScript

Slide 2

Slide 2 text

Buenas !

Slide 3

Slide 3 text

Brendan Eich criador do JS

Slide 4

Slide 4 text

Jean Carlo Emer [ 'github', 'speakerdeck', 'twitter' ].map(service => service + '.com/jcemer'; ); artesão da internet

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

fantástico JavaScript é ?

Slide 8

Slide 8 text

mil pessoas 21% do GitHub ubíqua

Slide 9

Slide 9 text

Sobre a palestra • Paradigmas • Organização de código • Modularização • Novas funcionalidades da ES6

Slide 10

Slide 10 text

paradigmas ! /Appl lement||window.HTM return!0;var a=document.createEl gment:"]*>([\\S\\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

Slide 11

Slide 11 text

• 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]

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

• 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

Slide 14

Slide 14 text

• Higher-order functions Funções como argumentos ou valores de retorno var fn = function () { /* ... */ }; document.addEventListener('click', fn); !function () { ! return function () { /* ... */ }; }();

Slide 15

Slide 15 text

É muito afude* ter objetos e funções de primeira classe ! * afude: legal

Slide 16

Slide 16 text

/Appl lement||window.HTM return!0;var a=document.createEl gment:"]*>([\\S\\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

Slide 17

Slide 17 text

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);

Slide 18

Slide 18 text

Quase tudo é objeto ou pode ser convertido para automaticamente !

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

• 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

Slide 21

Slide 21 text

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!

Slide 22

Slide 22 text

Object String 'BrazilJS' { current: 0 } Array [1, 2, 3] ? ...

Slide 23

Slide 23 text

Criando construtores function Counter() { this.current = 0; } var sample = new Counter(); sample.current; // 0 sample.constructor; // function Counter() { // this.current = 0 // }

Slide 24

Slide 24 text

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; };

Slide 25

Slide 25 text

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 }

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

delete sample.toString; Counter.prototype.toString = function() { return this.current + ' yeah'; }; alert(sample); 0 yeah

Slide 28

Slide 28 text

Nosso primeiro construtor: função prototype, e new !

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

Herança?! Deixa disto! O que você precisa mesmo é de composição

Slide 31

Slide 31 text

1 ~ Composição function Counter(min, max, current) { /* ... */ } function Spinner() { /* ... */ } function Carousel(itens) { this.counter = new Counter(0, itens.length) this.loading = new Spinner() }

Slide 32

Slide 32 text

E se eu precisar de um construtor igual ao Counter mas com goToLast ?

Slide 33

Slide 33 text

O fantástico mundo do CoffeeScript ->

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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 } }

Slide 38

Slide 38 text

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 }

Slide 39

Slide 39 text

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) { /* ... */ }

Slide 40

Slide 40 text

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 } }

Slide 41

Slide 41 text

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 } }

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

ES6 classes class Counter { /* ... */ } class CounterPlus extends Counter { goToLast() { this.current = this.max } }

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

3 ~ Mixin var validateMixin = { ! validate: function () { /* ... */ } } var eventsMixin = { ! subscribe: function () { /* ... */ }, ! publish: function () { /* ... */ } } function Model() { ! /* ... */ } $.extend(Model.prototype, validateMixin, eventsMixin)

Slide 46

Slide 46 text

Recapitulando técnicas • Composição Contendo outros construtores que implementam funcionalidades • Herança Via cadeia de prototype • Mixin Estendendo o prototype

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

/Appl lement||window.HTM return!0;var a=document.createEl gment:"]*>([\\S\\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 }

Slide 49

Slide 49 text

• 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

Slide 50

Slide 50 text

• 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

Slide 51

Slide 51 text

É poderoso: funções construtoras, new, call e de bônus o prototype !

Slide 52

Slide 52 text

]*>([\\ 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 ->

Slide 53

Slide 53 text

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]

Slide 54

Slide 54 text

Arrays extras • Métodos para manipular arrays vindos da especificação do ES5

Slide 55

Slide 55 text

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]

Slide 56

Slide 56 text

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]

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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]}

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

/Appl lement||window.HTM return!0;var a=document.createEl gment:"]*>([\\S\\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

Slide 64

Slide 64 text

Um paradigma não exclui o outro! • Orientação a objetos Comportamento e estado • Funcional Computação baseada em transformação dos dados

Slide 65

Slide 65 text

Como mantenho informações privadas em meu código ?

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

Eu não escondo com frequência. Mas quando o faço, usar closure é a única opção Michael Fogus

Slide 68

Slide 68 text

Closure?! • Função que captura variáveis do escopo em que é definida var counter = (function(){ var current = 0 return function closure () { return current++ } })()

Slide 69

Slide 69 text

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()

Slide 70

Slide 70 text

Ok, agora tenho meu código privado !

Slide 71

Slide 71 text

[...], 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

Slide 72

Slide 72 text

[...], 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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

>([\\ 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 ( )

Slide 76

Slide 76 text

• Peças isoladas que podem ser adicionadas e removidas quando necessário • Devem poder indicar demais peças que constituem dependência

Slide 77

Slide 77 text

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) { /* ... */} } })()

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

AMD Asyncronous Module Definition define(['util'], function (util) { var data = {} function set (element, key, value) { /* ... */ } function get (element, key) { /* ... */} return { set: set , get: get } })

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

CJS CommonJS module var util = require('util') , data = {} function set (element, key, value) { /* ... */ } function get (element, key) { /* ... */} exports = { set: set , get: get }

Slide 82

Slide 82 text

• 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

Slide 83

Slide 83 text

ES6 modules

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

JSPM module loader • Suporta ES6, AMD e CJS • Utiliza o protocolo SPDY JSPM http:/ /jspm.io SPDY http:/ /en.wikipedia.org/wiki/SPDY

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

Perguntas ? @jcemer

Slide 90

Slide 90 text

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' )

Slide 91

Slide 91 text

fantástico JavaScript é ?

Slide 92

Slide 92 text

Obrigado ! @jcemer