Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Evolução e futuro do uso de paradigmas no JavaScript

2,567 views

Published on

Uma palestra sobre os paradigmas trazidos por bibliotecas e framework como Backbone.js, Angular.js e React. Conheceremos os principais conceitos por trás de programação imperativa, funcional e reativa. Por fim, teremos uma visão clara do quanto evoluímos e o que ainda está por vir na forma e uso da linguagem.

Published in: Technology

Evolução e futuro do uso de paradigmas no JavaScript

  1. 1. Paradigmas no JavaScript evolução e 
 futuro do uso de
  2. 2. jcemer.com github.com/jcemer twitter.com/jcemer speakerdeck.com/jcemer
  3. 3. porto alegre talentos.globo.com
  4. 4. Assim como a maioria das linguagens, o JavaScript atende a uma série de paradigmas
  5. 5. Existe confusão e falta de entendimento de como os paradigmas funcionam e se relacionam
  6. 6. Esta é uma palestra avançada (e extensa) sobre programação e JavaScript
  7. 7. Programando de maneira imperativa
  8. 8. Solução baseada em uma sequência de passos
  9. 9. <SCRIPT> 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); </SCRIPT> http://www.sislands.com/coin70/week7/counter.htm if e else
  10. 10. <SCRIPT> // 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>"); </SCRIPT> http://www.sislands.com/coin70/week2/NestedLoops1.htm foooorr
  11. 11. Código que explicitamente altera o estado e fluxo de execução do programa
  12. 12. Difícil de manter, reusar e evoluir
  13. 13. REQ HTML CLICK JSO N G EN E ADD JSON CLICK UE RATE ST
  14. 14. O surgimento de tecnologias foi essencial para o aperfeiçoamento do uso de paradigmas
  15. 15. A comunidade foi o principal agente
  16. 16. Orientando a objetos com protótipos
  17. 17. Solução baseada em um conjunto de objetos e troca de mensagens entre eles
  18. 18. Prototype.js a saudosa
  19. 19. 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
  20. 20. Objetos são instâncias de um construtor e mantêm estado
  21. 21. Todo construtor deve possuir uma única responsabilidade Single responsibility principle http://www.infoq.com/br/news/2014/02/solid-principios-javascript
  22. 22. Até mesmo as tarefas mais simples eram complexas utilizando Web APIs
  23. 23. Abstrações Orientando a objetos com protótipos
  24. 24. new Ajax.Request('/some_url', { method:'get', onSuccess: function(transport) { var response = transport.responseText alert("Success! nn" + response) }, onFailure: function() { alert('Something went wrong...') } }) http://prototypejs.org/learn/introduction-to-ajax
  25. 25. 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
  26. 26. Abstrações servem para isolar a complexidade de uma operação
  27. 27. Abstrações normalizam e delegam operações
  28. 28. Em alguns casos parecia mais fácil estender
  29. 29. 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
  30. 30. DOM extension is one of the biggest mistakes Prototype.js has ever done. http://perfectionkills.com/whats-wrong-with-extending-the-dom - Kangax
  31. 31. 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
  32. 32. jQuery a unipresente
  33. 33. $('li').hide() http://jqfundamentals.com/chapter/jquery-basics
  34. 34. jQuery possui as mesmas operações da Prototype.js implementas da maneira correta
  35. 35. Encadeando operações Orientando a objetos 
 com protótipos
  36. 36. $('li') .click(function () { $(this).addClass('clicked') }) .find('span') .attr('title', 'Hover over me') http://jqfundamentals.com/chapter/jquery-basics
  37. 37. Encadeamento permite executar uma série de operações em um mesmo objeto
  38. 38. A biblioteca padrão do JavaScript é pobre e obscura
  39. 39. Aprimorando a biblioteca padrão Orientando a objetos 
 com protótipos
  40. 40. Underscore.js a útil
  41. 41. var toString = Object.prototype.toString toString.call("Oops") == "[object String]" _.isString("Opps") Com underscore.js
  42. 42. - 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
  43. 43. Operações utilitárias 
 são essenciais para um código mais legível
  44. 44. Invariavelmente seus projetos enfrentarão os mesmos problemas
  45. 45. Código modularizado Orientando a objetos 
 com protótipos
  46. 46. Módulos separam porções de código que possuem algo em comum
  47. 47. Módulos são coesos, desacoplados e reusáveis
  48. 48. Lodash a modular
  49. 49. 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
  50. 50. 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
  51. 51. 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
  52. 52. DEPENDÊNCIA DUPLICAÇÃO VS A manutenção do equilíbrio, reduzindo a duplicação
 David Chelimsky 
 https://www.youtube.com/watch?v=ugTQF2uw9eg
  53. 53. O importante é definir bem o critério de modularização
  54. 54. JavaScript suporta diferentes padrões de módulos, escolha um http://eloquentjavascript.net/10_modules.html
  55. 55. Programando de maneira funcional
  56. 56. Solução baseada em transformação de valores
  57. 57. https://smthngsmwhr.wordpress.com/2014/02/02/eloquent-javascript- with-underscore-js First-class functions movem o JavaScript significativamente em direção a FP
  58. 58. Funções podem ser passadas e retornados por outras funções First-class functions
  59. 59. Underscore.js a funcional
  60. 60. _.reduce(collection, function(a, b) { return a + b }) _.filter(collection, function(n) { return (n % 2) === 0 }) Livro: Introducing Functional Programming with Underscore.js
  61. 61. Construções funcionais são mais fáceis de ler e manter
  62. 62. 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
  63. 63. Ausência de estado compartilhado, funções que não geram efeito colateral Funções puras
  64. 64. Programação funcional vai muito além de manipulação de coleções
  65. 65. 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)
  66. 66. 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
  67. 67. http://documentcloud.github.io/underscore-contrib#curry _.curry(function (store, next, action) { // [...] }) Underscore-contrib
  68. 68. 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
  69. 69. Mas nem tudo está disponível: é preciso aprender a esperar por operações assíncronas
  70. 70. getFiles('.', function (files) { generateIndex(files, function () { generatePosts(files, ready) }) }) Funções que geram um blog
  71. 71. 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
  72. 72. Utilizando Promises Programando de maneira 
 funcional
  73. 73. 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
  74. 74. 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
  75. 75. http://tableless.com.br/fluxo-de-execucao-assincrono-em-javascript- promises blogParser.start() .then(getFiles) .then(generateIndex) .then(generatePosts) Utilizando Promises/A+
  76. 76. Interfaces basicamente reagem a eventos vindos do usuário e servidor
  77. 77. Programando orientado a eventos
  78. 78. Solução guiada pela ocorrência de eventos externos
  79. 79. Web APIs são massivamente apoiadas no paradigma de eventos
  80. 80. Backbone.js o organizado
  81. 81. Backbone.js faz seus dados funcionarem igual ao DOM: emitindo eventos
  82. 82. Apresentar palestra na RubyConf
  83. 83. 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 } })
  84. 84. 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 } })
  85. 85. 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 } })
  86. 86. O DOM não é performático quando aplicamos modificações a revelia
  87. 87. 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) } });
  88. 88. Neste cenário é que o 
 data-binding fez rir e chorar
  89. 89. data $scope.Field = "data" Data-binding
  90. 90. $scope.Field = "data" Two-way data-binding data
  91. 91. AngularJS o benevolente
  92. 92. <div ng-controller="TaskCtrl" ng-click="change()"> <span>{{ done ? 'Ok' : '' }}</span> {{ description }} </div> app.controller('TaskCtrl', function($scope) { $scope.description = 'My task' $scope.change = function () { $scope.done = true } }) HTML? JavaScript
  93. 93. 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
  94. 94. React.JS o vanguardista
  95. 95. var Task = React.createClass({ getInitialState: function () { return {done: false} }, render: function () { return <div onClick={this.change}> {this.state.done ? 'Ok' : ''} {this.props.description}</div> }, change: function () { this.setState({done: true}) } }) React.render(<Task description='My task' />, document.body) XML?!
  96. 96. var Task = React.createClass({ getInitialState: function () { return {done: false} }, render: function () { return <div onClick={this.change}> {this.state.done ? 'Ok' : ''} {this.props.description}</div> }, change: function () { this.setState({done: true}) } }) React.render(<Task description='My task' />, document.body)
  97. 97. var Task = React.createClass({ getInitialState: function () { return {done: false} }, render: function () { return <div onClick={this.change}> {this.state.done ? 'Ok' : ''} {this.props.description}</div> }, change: function () { this.setState({done: true}) } }) React.render(<Task description='My task' />, document.body) Estado
  98. 98. 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
  99. 99. 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)
  100. 100. Componentes mantêm estado e recebem propriedades dos seus ancestrais
  101. 101. Set state Dirty Re-render React Components http://calendar.perfplanet.com/2013/diff/
  102. 102. 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
  103. 103. React.js♥
  104. 104. Ainda precisamos lidar com eventos a todo tempo
  105. 105. instant search
  106. 106. var onType = _.debounce(function() { $.get('data.json') }, 300) Buscar depois de 300ms de inatividade
  107. 107. var onType = _.debounce(function() { $.get('data.json') }, 300) Buscar depois de 300ms de inatividade ZzzZzzZz...
  108. 108. E se as request não retornarem na ordem?!
  109. 109. Programando de maneira funcional reativa
  110. 110. Solução guiada por streams de dados assíncronos
  111. 111. Stream é uma sequência de eventos ordenados no tempo
  112. 112. var text = $('#input') .asEventStream('keydown') .debounce(300) .map(function(event) { return event.target.value }) https://baconjs.github.io instant search
  113. 113. text BACO NJS Debonced 300ms
  114. 114. 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) })
  115. 115. text BACO NJS Query BACO Query BACONJS Request para a nuvem
  116. 116. text results BACO NJS Query BACO Query BACONJS Ops
  117. 117. 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
  118. 118. text results BACO NJS Query BACO Query BACONJS x http://nullzzz.blogspot.com.br/2012/12/baconjs-tutorial-part-iii-ajax-and-stuff.html
  119. 119. FRP é sobre relações dependentes que se estabilizam com o passar do tempo https://www.zweitag.de/en/blog/technology/functional-reactive- programming-frp
  120. 120. Conhecer paradigmas e práticas vai além de sair implementando em projetos
  121. 121. Compreender contextos e aplicar as soluções mais adequadas é o mais importante
  122. 122. só, por favor, 
 não usem o maldito ;
  123. 123. @jcemer Obrigado

×