Slide 1

Slide 1 text

Paradigmas no JavaScript evolução e 
 futuro do uso de

Slide 2

Slide 2 text

jcemer.com github.com/jcemer twitter.com/jcemer speakerdeck.com/jcemer

Slide 3

Slide 3 text

porto alegre talentos.globo.com

Slide 4

Slide 4 text

Assim como a maioria das linguagens, o JavaScript atende a uma série de paradigmas

Slide 5

Slide 5 text

Existe confusão e falta de entendimento de como os paradigmas funcionam e se relacionam

Slide 6

Slide 6 text

Esta é uma palestra avançada (e extensa) sobre programação e JavaScript

Slide 7

Slide 7 text

Programando de maneira imperativa

Slide 8

Slide 8 text

Solução baseada em uma sequência de passos

Slide 9

Slide 9 text

var visits = getCookie("counter"); if (visits) { visits = parseInt(visits) + 1; document.write("By the way, you have been here " + visits + 
 " times."); } else { visits = 1; document.write("By the way, this is your first time here."); } setCookie("counter", visits); http://www.sislands.com/coin70/week7/counter.htm if e else

Slide 10

Slide 10 text

// Use single-spaced text for Multiplication table document.write("<CENTER><BLOCKQUOTE><STRONG><PRE><FONT COLOR='FF0000'">) var i, j, total; // global variables for (i = 1; i <= 10; i++) { for (j = 1; j < 10; j++) { total = i * j; total = " " + total //add space before each number // Add another space before single digits if (total < 10) total = " " + total; // Display result document.write(total); } // end inner j loop document.write("<BR>"); // end of line break } // end of i outer loop document.write("</FONT></PRE></STRONG></BLOCKQUOTE></CENTER>"); http://www.sislands.com/coin70/week2/NestedLoops1.htm foooorr

Slide 11

Slide 11 text

Código que explicitamente altera o estado e fluxo de execução do programa

Slide 12

Slide 12 text

Difícil de manter, reusar e evoluir

Slide 13

Slide 13 text

REQ HTML CLICK JSO N G EN E ADD JSON CLICK UE RATE ST

Slide 14

Slide 14 text

O surgimento de tecnologias foi essencial para o aperfeiçoamento do uso de paradigmas

Slide 15

Slide 15 text

A comunidade foi o principal agente

Slide 16

Slide 16 text

Orientando a objetos com protótipos

Slide 17

Slide 17 text

Solução baseada em um conjunto de objetos e troca de mensagens entre eles

Slide 18

Slide 18 text

Prototype.js a saudosa

Slide 19

Slide 19 text

var Person = Class.create({ initialize: function(name) { this.name = name }, say: function(message) { return this.name + ': ' + message } }) var Pirate = Class.create(Person, { say: function($super, message) { return $super(message) + ', yarr!' } }) http://prototypejs.org/learn/class-inheritance herança

Slide 20

Slide 20 text

Objetos são instâncias de um construtor e mantêm estado

Slide 21

Slide 21 text

Todo construtor deve possuir uma única responsabilidade Single responsibility principle http://www.infoq.com/br/news/2014/02/solid-principios-javascript

Slide 22

Slide 22 text

Até mesmo as tarefas mais simples eram complexas utilizando Web APIs

Slide 23

Slide 23 text

Abstrações Orientando a objetos com protótipos

Slide 24

Slide 24 text

new Ajax.Request('/some_url', { method:'get', onSuccess: function(transport) { var response = transport.responseText alert("Success! \n\n" + response) }, onFailure: function() { alert('Something went wrong...') } }) http://prototypejs.org/learn/introduction-to-ajax

Slide 25

Slide 25 text

getTransport: function() { return Try.these( function() {return new XMLHttpRequest()}, function() {return new ActiveXObject('Msxml2.XMLHTTP')}, function() {return new ActiveXObject('Microsoft.XMLHTTP')} ) || false } Código fonte da versão 1.7.2.0 da Prototype.js Operação interna do Request

Slide 26

Slide 26 text

Abstrações servem para isolar a complexidade de uma operação

Slide 27

Slide 27 text

Abstrações normalizam e delegam operações

Slide 28

Slide 28 text

Em alguns casos parecia mais fácil estender

Slide 29

Slide 29 text

if (!document.getElementsByClassName) 
 document.getElementsByClassName = function(instanceMethods){ Código fonte da versão 1.7.2.0 da Prototype.js Object.extend(Function.prototype, (function() { var ELEMENT_PROTOTYPE = window.HTMLElement ? HTMLElement.prototype : Element.prototype; Estender document Estender construtor de função Estender objetos do DOM

Slide 30

Slide 30 text

DOM extension is one of the biggest mistakes Prototype.js has ever done. http://perfectionkills.com/whats-wrong-with-extending-the-dom - Kangax

Slide 31

Slide 31 text

Modificar objetos que não pertencem ao seu código não é uma boa prática https://www.nczonline.net/blog/2010/03/02/maintainable-javascript- dont-modify-objects-you-down-own

Slide 32

Slide 32 text

jQuery a unipresente

Slide 33

Slide 33 text

$('li').hide() http://jqfundamentals.com/chapter/jquery-basics

Slide 34

Slide 34 text

jQuery possui as mesmas operações da Prototype.js implementas da maneira correta

Slide 35

Slide 35 text

Encadeando operações Orientando a objetos 
 com protótipos

Slide 36

Slide 36 text

$('li') .click(function () { $(this).addClass('clicked') }) .find('span') .attr('title', 'Hover over me') http://jqfundamentals.com/chapter/jquery-basics

Slide 37

Slide 37 text

Encadeamento permite executar uma série de operações em um mesmo objeto

Slide 38

Slide 38 text

A biblioteca padrão do JavaScript é pobre e obscura

Slide 39

Slide 39 text

Aprimorando a biblioteca padrão Orientando a objetos 
 com protótipos

Slide 40

Slide 40 text

Underscore.js a útil

Slide 41

Slide 41 text

var toString = Object.prototype.toString toString.call("Oops") == "[object String]" _.isString("Opps") Com underscore.js

Slide 42

Slide 42 text

- keys - allKeys - values - mapObject - pairs - invert - create - functions - findKey - extend - extendOwn - pick - omit - defaults - clone - tap - has - property - propertyOf - isEqual - isMatch - isEmpty - isElement - isArray - isObject - isArguments - isFunction - isString - isNumber - isFinite - isBoolean - isDate - isRegExp - isNaN - isUndefined - noConflict - identity - constant - noop - times - random - mixin - iteratee - uniqueId - escape - unescape - result - now - template - isNull - matcher

Slide 43

Slide 43 text

Operações utilitárias 
 são essenciais para um código mais legível

Slide 44

Slide 44 text

Invariavelmente seus projetos enfrentarão os mesmos problemas

Slide 45

Slide 45 text

Código modularizado Orientando a objetos 
 com protótipos

Slide 46

Slide 46 text

Módulos separam porções de código que possuem algo em comum

Slide 47

Slide 47 text

Módulos são coesos, desacoplados e reusáveis

Slide 48

Slide 48 text

Lodash a modular

Slide 49

Slide 49 text

var methods = ['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error']; _.each(methods, function(name) { _['is' + name] = function(obj) { return toString.call(obj) === '[object ' + name + ']'; }; }); underscore.js

Slide 50

Slide 50 text

var isObjectLike = require('./isObjectLike'); var stringTag = '[object String]'; var objectProto = global.Object.prototype; var objToString = objectProto.toString; function isString(value) { return typeof value == 'string' || 
 (isObjectLike(value) 
 && objToString.call(value) == stringTag); } module.exports = isString; lang/isString.js

Slide 51

Slide 51 text

var isObjectLike = require('./isObjectLike'); var numberTag = '[object Number]'; var objectProto = global.Object.prototype; var objToString = objectProto.toString; function isNumber(value) { return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); } module.exports = isNumber; lang/isNumber.js

Slide 52

Slide 52 text

DEPENDÊNCIA DUPLICAÇÃO VS A manutenção do equilíbrio, reduzindo a duplicação
 David Chelimsky 
 https://www.youtube.com/watch?v=ugTQF2uw9eg

Slide 53

Slide 53 text

O importante é definir bem o critério de modularização

Slide 54

Slide 54 text

JavaScript suporta diferentes padrões de módulos, escolha um http://eloquentjavascript.net/10_modules.html

Slide 55

Slide 55 text

Programando de maneira funcional

Slide 56

Slide 56 text

Solução baseada em transformação de valores

Slide 57

Slide 57 text

https://smthngsmwhr.wordpress.com/2014/02/02/eloquent-javascript- with-underscore-js First-class functions movem o JavaScript significativamente em direção a FP

Slide 58

Slide 58 text

Funções podem ser passadas e retornados por outras funções First-class functions

Slide 59

Slide 59 text

Underscore.js a funcional

Slide 60

Slide 60 text

_.reduce(collection, function(a, b) { return a + b }) _.filter(collection, function(n) { return (n % 2) === 0 }) Livro: Introducing Functional Programming with Underscore.js

Slide 61

Slide 61 text

Construções funcionais são mais fáceis de ler e manter

Slide 62

Slide 62 text

array.forEach(iteratee) array.map(iteratee) array.reduce(iteratee, memo) array.every(predicate) array.find(predicate) array.includes(element) [...arguments] Object.keys(object) https://www.reindex.io/blog/you-might-not-need-underscore ES 5.1 + ES2015 + ES2016

Slide 63

Slide 63 text

Ausência de estado compartilhado, funções que não geram efeito colateral Funções puras

Slide 64

Slide 64 text

Programação funcional vai muito além de manipulação de coleções

Slide 65

Slide 65 text

var mult = function (a, b) { return a * b } var negate = _.partial(mult, -1) var mult2 = _.partial(mult, 2) var square = function (n) { return n * n } var result = _.compose(negate, mult2, square)

Slide 66

Slide 66 text

export default store => next => action => { // [...] } https://github.com/rackt/redux/blob/master/examples/real-world/ middleware/api.js export default function (store) { return function (next) { return function (action) { } } } Portando para ES 5.1 Código original

Slide 67

Slide 67 text

http://documentcloud.github.io/underscore-contrib#curry _.curry(function (store, next, action) { // [...] }) Underscore-contrib

Slide 68

Slide 68 text

Funções precisam aceitar e retornar dados imutáveis // frozen value type const xy = #[ x, y ] // functional extension const xyz = #[ ...xy, z ] https://github.com/sebmarkbage/ecmascript-immutable-data-structures

Slide 69

Slide 69 text

Mas nem tudo está disponível: é preciso aprender a esperar por operações assíncronas

Slide 70

Slide 70 text

getFiles('.', function (files) { generateIndex(files, function () { generatePosts(files, ready) }) }) Funções que geram um blog

Slide 71

Slide 71 text

Programação funcional é sobre valores e suas relações https://blog.jcoglan.com/2013/03/30/callbacks-are-imperative- promises-are-functional-nodes-biggest-missed-opportunity

Slide 72

Slide 72 text

Utilizando Promises Programando de maneira 
 funcional

Slide 73

Slide 73 text

Promises são valores que representam o possível resultado de uma operação assíncrona http://tableless.com.br/fluxo-de-execucao-assincrono-em- javascript-promises

Slide 74

Slide 74 text

https://blog.jcoglan.com/2011/03/11/promises-are-the-monad-of- asynchronous-programming pipe([getFiles, generateIndex, generatePosts]) Promises are the monad of asynchronous programming

Slide 75

Slide 75 text

http://tableless.com.br/fluxo-de-execucao-assincrono-em-javascript- promises blogParser.start() .then(getFiles) .then(generateIndex) .then(generatePosts) Utilizando Promises/A+

Slide 76

Slide 76 text

Interfaces basicamente reagem a eventos vindos do usuário e servidor

Slide 77

Slide 77 text

Programando orientado a eventos

Slide 78

Slide 78 text

Solução guiada pela ocorrência de eventos externos

Slide 79

Slide 79 text

Web APIs são massivamente apoiadas no paradigma de eventos

Slide 80

Slide 80 text

Backbone.js o organizado

Slide 81

Slide 81 text

Backbone.js faz seus dados funcionarem igual ao DOM: emitindo eventos

Slide 82

Slide 82 text

Apresentar palestra na RubyConf

Slide 83

Slide 83 text

var TaskView = Backbone.View.extend({ events: { 'click [data-check]': 'done' }, done: function (event) { this.model.set({done: true}) }, initialize: function () { this.listenTo(this.model, 'change', this.render) }, render: function () { // build task HTML } })

Slide 84

Slide 84 text

var TaskView = Backbone.View.extend({ events: { 'click [data-check]': 'done' }, done: function (event) { this.model.set({done: true}) }, initialize: function () { this.listenTo(this.model, 'change', this.render) }, render: function () { // build task HTML } })

Slide 85

Slide 85 text

var TaskView = Backbone.View.extend({ events: { 'click [data-check]': 'done' }, done: function (event) { this.model.set({done: true}) }, initialize: function () { this.listenTo(this.model, 'change', this.render) }, render: function () { // build task HTML } })

Slide 86

Slide 86 text

O DOM não é performático quando aplicamos modificações a revelia

Slide 87

Slide 87 text

var TaskView = Backbone.View.extend({ //... initialize: function () { this.listenTo(this.model, 'change:done', this.renderStatus) }, renderStatus: function () { var done = this.model.get('done') ? 'ok' : '' this.$('[data-status]').text(text) } });

Slide 88

Slide 88 text

Neste cenário é que o 
 data-binding fez rir e chorar

Slide 89

Slide 89 text

data $scope.Field = "data" Data-binding

Slide 90

Slide 90 text

$scope.Field = "data" Two-way data-binding data

Slide 91

Slide 91 text

AngularJS o benevolente

Slide 92

Slide 92 text

{{ done ? 'Ok' : '' }} {{ description }}
app.controller('TaskCtrl', function($scope) { $scope.description = 'My task' $scope.change = function () { $scope.done = true } }) HTML? JavaScript

Slide 93

Slide 93 text

http://leoasis.github.io/posts/2014/10/28/think-twice-or-thrice- before-using-angular http://tutorials.jenkov.com/angularjs/critique.html https://medium.com/@mnemon1ck/why-you-should-not-use- angularjs-1df5ddf6fc99 Think Twice (or Thrice) Before Using Angular

Slide 94

Slide 94 text

React.JS o vanguardista

Slide 95

Slide 95 text

var Task = React.createClass({ getInitialState: function () { return {done: false} }, render: function () { return
{this.state.done ? 'Ok' : ''} {this.props.description}
}, change: function () { this.setState({done: true}) } }) React.render(, document.body) XML?!

Slide 96

Slide 96 text

var Task = React.createClass({ getInitialState: function () { return {done: false} }, render: function () { return
{this.state.done ? 'Ok' : ''} {this.props.description}
}, change: function () { this.setState({done: true}) } }) React.render(, document.body)

Slide 97

Slide 97 text

var Task = React.createClass({ getInitialState: function () { return {done: false} }, render: function () { return
{this.state.done ? 'Ok' : ''} {this.props.description}
}, change: function () { this.setState({done: true}) } }) React.render(, document.body) Estado

Slide 98

Slide 98 text

Manipular e manter o histórico dos estados do DOM é difícil. A solução é escrever código como se você recriasse o DOM toda vez que o estado muda https://github.com/Matt-Esch/virtual-dom

Slide 99

Slide 99 text

Já existe um esquema gratuito para o fluxo dos dados: O DOM http://www.code-experience.com/why-you-might-not-need-mvc-with- reactjs/ (os eventos e CSS já utilizam)

Slide 100

Slide 100 text

Componentes mantêm estado e recebem propriedades dos seus ancestrais

Slide 101

Slide 101 text

Set state Dirty Re-render React Components http://calendar.perfplanet.com/2013/diff/

Slide 102

Slide 102 text

var newTree = render(data) var patches = diff(tree, newTree) rootNode = patch(rootNode, patches) tree = newTree Patch! Virtual DOM https://github.com/Matt-Esch/virtual-dom

Slide 103

Slide 103 text

React.js ♥

Slide 104

Slide 104 text

Ainda precisamos lidar com eventos a todo tempo

Slide 105

Slide 105 text

instant search

Slide 106

Slide 106 text

var onType = _.debounce(function() { $.get('data.json') }, 300) Buscar depois de 300ms de inatividade

Slide 107

Slide 107 text

var onType = _.debounce(function() { $.get('data.json') }, 300) Buscar depois de 300ms de inatividade ZzzZzzZz...

Slide 108

Slide 108 text

E se as request não retornarem na ordem?!

Slide 109

Slide 109 text

Programando de maneira funcional reativa

Slide 110

Slide 110 text

Solução guiada por streams de dados assíncronos

Slide 111

Slide 111 text

Stream é uma sequência de eventos ordenados no tempo

Slide 112

Slide 112 text

var text = $('#input') .asEventStream('keydown') .debounce(300) .map(function(event) { return event.target.value }) https://baconjs.github.io instant search

Slide 113

Slide 113 text

text BACO NJS Debonced 300ms

Slide 114

Slide 114 text

var text = $('#input') .asEventStream('keydown') .debounce(300) .map(function(event) { return event.target.value }) function movieSearch(query) { return Bacon.fromPromise(queryMovie(query))} text.flatMap(movieSearch) .onValue(function(results) { console.log(results) })

Slide 115

Slide 115 text

text BACO NJS Query BACO Query BACONJS Request para a nuvem

Slide 116

Slide 116 text

text results BACO NJS Query BACO Query BACONJS Ops

Slide 117

Slide 117 text

var text = $('#input') .asEventStream('keydown') .debounce(300) .map(function(event) { return event.target.value }) function movieSearch(query) { return Bacon.fromPromise(queryMovie(query))} text.flatMapLatest(movieSearch) .onValue(function(results) { console.log(results) }) latest

Slide 118

Slide 118 text

text results BACO NJS Query BACO Query BACONJS x http://nullzzz.blogspot.com.br/2012/12/baconjs-tutorial-part-iii-ajax-and-stuff.html

Slide 119

Slide 119 text

FRP é sobre relações dependentes que se estabilizam com o passar do tempo https://www.zweitag.de/en/blog/technology/functional-reactive- programming-frp

Slide 120

Slide 120 text

No content

Slide 121

Slide 121 text

Conhecer paradigmas e práticas vai além de sair implementando em projetos

Slide 122

Slide 122 text

Compreender contextos e aplicar as soluções mais adequadas é o mais importante

Slide 123

Slide 123 text

só, por favor, 
 não usem o maldito ;

Slide 124

Slide 124 text

@jcemer Obrigado