Javascript avançado<br />Ricardo Cavalcanti<br />kvalcanti@gmail.com<br />
Algumas Ferramentas<br />“Firebug integrates with Firefox to put a wealth of web development tools at your fingertips whil...
Prototype: introdução<br />Não é a biblioteca prototype.js<br />Javascript usa protótipos no seu modelo de objetos<br />O ...
Prototype: a propriedade prototype<br />Todo objeto tem uma propriedade prototype<br />Ao tenta acessar uma propriedade in...
Prototype: aumentando prototypes<br />Ao incluir propriedades e funções ao prototype de um construtor,  elas são incluidas...
Prototype: mudando o prototype<br />Mudanças no prototype afetam todas as instâncias<br />var cat = newCat("Barsik");<br /...
Prototype: propriedades<br />O objeto pode ter suas próprias propriedades<br />A delegação cuida da prioridade<br />functi...
Prototype: estendendo JS Objects<br />Podemos estender inclusive os JS Objects<br />String.prototype.trim = function(){<br...
Herança<br />
Herança clássica<br />Objetos são instancias de classes<br />Classes herdam de outra classe<br />
Herança prototípica<br />Não há classes<br />Objetos herdam de objetos<br />Um objeto tem um link para outro objeto<br />N...
Herança prototípica<br />var oldObject = {<br />firstMethod: function(){...},<br />secondMethod: function(){...},<br />};<...
Herança prototípica<br />Ao acessar uma propriedade, o interpretador vai primeiro no objeto, <br />depois busca no protóti...
Herança prototípica<br />Mudanças no oldObject serão visíveis no newObject, como já vimos<br />Mudanças no newObject não a...
Herança pseudoclássica<br />Com herança prototípica pura, a linguagem deve ter um operador como a função Object<br />Para ...
Pseudoclássica<br />Três mecanismos:<br />Funções Contruturas<br />O operador new<br />O atributo prototype, nas funções<b...
Operador new<br />functionContructor(){<br />this.member = ...;<br />}<br />Contructor.prototype.firstMethod = function(a,...
Operador new<br />newConstructor() retorno um novo objeto ligado ao Constructor.prototype<br />newObject<br />oldObject<br...
Operador new<br />A função Contructor() pasa o novo objeto na variável this<br />Para inicizar o novo objeto<br />newObjec...
prototype<br />Cada objeto function criado tem um atributo prototype<br />O prototype tem um atributo constructor, que ref...
Herança Pseudoclássica<br />É possível simular herança clássica atribuindo um objeto criado por um constutor como o protót...
functionSuperClasse(){}<br />SuperClasse.prototype.hello = function(){alert('super hello')};<br />functionSubClasse(){};<b...
functionSuperClasse(){}<br />SuperClasse.prototype.name= 'super';<br />SuperClasse.prototype.hello= function(){alert(this....
Closures<br />
Escopo nas funções<br />O escopo é definido pelas funções, e não pelos blocos<br />Funções internas têm acesso às variávei...
Closures<br />Quando a função interna dura mais que a externa, o escopo externo é preservado<br />Isso se chama closure<br />
Um closure simples<br />var f = function(x){<br />  var m = function(y){<br />returnx * y;  <br />}<br />return m;<br />}<...
Usando closures<br />InformationHiding<br />Funções com timers<br />Eventhandlers<br />Callbacks<br />
Clojures: Dados privados <br />var quo = function (status) {<br />return {<br />get_status: function (  ) {<br />return st...
Closures: timers<br />var fade = function (node) {<br />    var level = 1;<br />    var step = function (  ) {<br />      ...
Closure: eventhandler<br />Função que adiciona um eventhandler para uma lista de nodes.<br />Ao clicar, alerta a ordem do ...
Closure: eventhandler<br />Exemplo correto<br />var add_the_handlers = function (nodes) {<br />    var i;<br />    for (i ...
Curry<br />
Curry<br />Funções são valores<br />É possível combinar uma função com alguns argumentos e produzir outra função<br />var ...
Função curry<br />Curry  cria um closure queguarda a função original e seusargumentospararealizar o currying<br />Quandoex...
Function.prototype.curry = function (  ) {<br />varargs = arguments, that = this;<br />    return function (  ) {<br />   ...
Função curry: final<br />Function.prototype.curry = function(  ) {<br />    var slice = Array.prototype.slice,<br />args =...
Closures: callbacks<br />var replace = function (el, url){<br />   var callback = function(t){<br />el.innerHTML = t;<br /...
Closures: cuidados<br />Evite criar funções em loops<br />Para evitar closures indesejados<br />Atenção com o this<br />Ma...
bind<br />
This<br />window.name= "thewindowobject"<br />functionscopeTest() {<br />returnthis.name<br />}<br />scopeTest()<br />// -...
Javascript é dinâmica<br />//atribuindo a função, SEM executá-la<br />window.test= foo.otherScopeTest<br />//chamando a fu...
Functionbind<br />Eu gostaria de escolher o ‘this’ da minha função<br />window.test = foo.otherScopeTest.bind(foo);<br />t...
Partes Feias<br />Ricardo Cavalcanti<br />kvalcanti@gmail.com<br />
Variáveis globais<br />Todas as coisas são carregadas no mesmo objeto global<br />var foo = value;<br />window.foo = value...
Escopo<br />Apesar da sintaxe de C<br />Blocos não criam escopo<br />O escopo é sempre da função<br />
Inserção de ;<br />Há um mecanismo de completar com ; alguns comandos<br />return ;<br />{ <br />status: true<br />};<br /...
Palavras reservadas<br />abstract booleanbreak byte case catch charclassconst continue debugger default delete do doubleel...
Unicode<br />char em Javascript tem 16bits<br />Um charunicode são 2 caracteres em javascript<br />
typeof<br />typeof 98.6  >> ‘number’<br />typeofnull >> ‘object’  <br />my_value === null  //melhor<br />if (my_value && ...
parseInt<br />Converte um string num integer<br />Para quando vê um não-dígito<br />parseInt("16") >> 16<br />parseInt("16...
Ponto fllutuante<br />Javascript usa IEEE Standard for Binary Floating-Point Arithmetic (IEEE 754)<br />Portanto<br />0.1 ...
NaN<br />Se algum operando for NaN, o resultado da operação será NaN<br />Converter um string em inteiro gera NaN<br />Por...
null e undefined<br />value = myObject[name]; <br />if (value == null) { <br />   alert(name + ' not found.'); <br />}<br ...
Partes ruins<br />
==<br />'' == '0'          // false<br />0 == ''            // true<br />0 == '0'           // true<br />false == 'false' ...
with<br />Para acessar os atributos de um objeto<br />Problemas:<br />with (obj) {<br />    a = b; <br />}<br />O mesmo qu...
eval<br />Evite!<br />Bem como outras formas que recebem código como string<br />Contrutor de Fuction<br />setTimeout<br /...
switch FallThrough<br />Switch-case sem break<br />Fonte de muitos erros, cuidado!<br />
Comandos sem bloco<br />Sempre use blocos nos comandos<br />if (ok)<br />    t = true;<br />if (ok)<br />    t = true;<br ...
Operadores de bits<br />Os mesmos de java<br />&    and<br />|    or<br />^    xor<br />~   not<br />>>   signed right shi...
TypedWrappers<br />Desnecessários<br />newBoolean(false)<br />Evite o uso de newBoolean, newNumber, new String<br />Também...
Para evitar erros<br />
Upcoming SlideShare
Loading in...5
×

Javascript avançado

3,756

Published on

Javacript Avançado: herança, closures, curry, bind, partes feias, partes ruins

Published in: Technology, Design
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,756
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
125
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Javascript avançado

  1. 1. Javascript avançado<br />Ricardo Cavalcanti<br />kvalcanti@gmail.com<br />
  2. 2. Algumas Ferramentas<br />“Firebug integrates with Firefox to put a wealth of web development tools at your fingertips while you browse. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page!”<br />http://getfirebug.com<br />
  3. 3. Prototype: introdução<br />Não é a biblioteca prototype.js<br />Javascript usa protótipos no seu modelo de objetos<br />O que importa é o que o objeto faz, e não de quem ele herda<br />Uma função construtora seta seu prototype no objetos que cria<br />
  4. 4. Prototype: a propriedade prototype<br />Todo objeto tem uma propriedade prototype<br />Ao tenta acessar uma propriedade inexistente, javascript busca a propriedade no prototype do objeto<br />E no prototype do prototype...<br />
  5. 5. Prototype: aumentando prototypes<br />Ao incluir propriedades e funções ao prototype de um construtor, elas são incluidas nos objetos que o construtor produz<br />var cat = newCat("Barsik");<br />Cat.prototype.animal = "cat";<br />Cat.prototype >> {animal: "cat"}<br />cat.animal >> "cat"<br />Cat.prototype.seeADog = function() {<br />return "I'm "+this.name+". Sshhhhhhh!";<br />}<br />cat.seeADog() >> "I'mBarsik. Sshhhhhhh!";<br />
  6. 6. Prototype: mudando o prototype<br />Mudanças no prototype afetam todas as instâncias<br />var cat = newCat("Barsik");<br />var cat2 = newCat("Murzik");<br />Cat.prototype.animal = "cat";<br />cat.animal >> "cat"<br />cat2.animal >> "cat“<br />Cat.prototype.animal = "dog";<br />cat.animal >> "dog"<br />cat2.animal >> "dog"<br />
  7. 7. Prototype: propriedades<br />O objeto pode ter suas próprias propriedades<br />A delegação cuida da prioridade<br />functionGadget(/*String*/ name) {<br />this.name = name;<br />}<br />var iphone = newGadget("iPhone");<br />Gadget.prototype.name = "none";<br />iphone.name >> "iPhone"<br />delete iphone.name;<br />iphone.name >> "none"<br />
  8. 8. Prototype: estendendo JS Objects<br />Podemos estender inclusive os JS Objects<br />String.prototype.trim = function(){<br /> return this.replace(/^s+|s+$/g, ''); <br />};<br />“ bla “.trim() >> “bla”<br />
  9. 9. Herança<br />
  10. 10. Herança clássica<br />Objetos são instancias de classes<br />Classes herdam de outra classe<br />
  11. 11. Herança prototípica<br />Não há classes<br />Objetos herdam de objetos<br />Um objeto tem um link para outro objeto<br />No Firefox é __proto__<br />var newObject = Object(oldObcet)<br />newObject<br />oldObject<br />__proto__<br />
  12. 12. Herança prototípica<br />var oldObject = {<br />firstMethod: function(){...},<br />secondMethod: function(){...},<br />};<br />var newObject = Object(oldObject);<br />newObject.thirdMethod = function(){...};<br />var anotherObject = Object(newObject);<br />anotherObject.thirdMethod();<br />
  13. 13. Herança prototípica<br />Ao acessar uma propriedade, o interpretador vai primeiro no objeto, <br />depois busca no protótipo do objeto,<br />...depois no protótipo do protótipo...<br />Até Object.prototype<br />newObject<br />oldObject<br />foo<br />2<br />foo<br />1<br />
  14. 14. Herança prototípica<br />Mudanças no oldObject serão visíveis no newObject, como já vimos<br />Mudanças no newObject não alteram o oldObject<br />newObject<br />oldObject<br />foo<br />2<br />foo<br />1<br />
  15. 15. Herança pseudoclássica<br />Com herança prototípica pura, a linguagem deve ter um operador como a função Object<br />Para criar novos objetos utilizando um já existente<br />Javascript usa operadores aparentemente clássicos<br />Mas que funcionam prototipicamente<br />
  16. 16. Pseudoclássica<br />Três mecanismos:<br />Funções Contruturas<br />O operador new<br />O atributo prototype, nas funções<br />
  17. 17. Operador new<br />functionContructor(){<br />this.member = ...;<br />}<br />Contructor.prototype.firstMethod = function(a,b) {...}<br />Contructor.prototype.secondMethod = function(a,b) {...}<br />var newObject = newConstructor();<br />
  18. 18. Operador new<br />newConstructor() retorno um novo objeto ligado ao Constructor.prototype<br />newObject<br />oldObject<br />newObject<br />Constructor.prototype<br />
  19. 19. Operador new<br />A função Contructor() pasa o novo objeto na variável this<br />Para inicizar o novo objeto<br />newObject<br />Constructor.prototype<br />
  20. 20. prototype<br />Cada objeto function criado tem um atributo prototype<br />O prototype tem um atributo constructor, que refencia o objeto function<br />Outros atributos adicionados no prototype da função serão vistos nos objetos constuídos com ela<br />É possível criar constantes e métodos par aos objetos<br />
  21. 21. Herança Pseudoclássica<br />É possível simular herança clássica atribuindo um objeto criado por um constutor como o protótipo de outra<br />Mas não é exatamente herança clássica<br />function BiggerConstructor(){};<br />BiggerConstructor.prototype = new MyContructor()<br />
  22. 22. functionSuperClasse(){}<br />SuperClasse.prototype.hello = function(){alert('super hello')};<br />functionSubClasse(){};<br />SubClasse.prototype = newSuperClasse();<br />SubClasse.prototype.subhello = function(){alert('sub hello')};<br />var o = newSubClasse();<br />o.hello();<br />o.subhello();<br />
  23. 23. functionSuperClasse(){}<br />SuperClasse.prototype.name= 'super';<br />SuperClasse.prototype.hello= function(){alert(this.name)};<br />functionSubClasse(){<br />this.name = 'sub';<br />};<br />SubClasse.prototype = newSuperClasse();<br />SubClasse.prototype.subhello = function(){alert(this.name)};<br />var o = newSubClasse();<br />o.hello();<br />o.subhello();<br />
  24. 24. Closures<br />
  25. 25. Escopo nas funções<br />O escopo é definido pelas funções, e não pelos blocos<br />Funções internas têm acesso às variáveis das funções externas<br />Exceto this e arguments<br />function f (){<br /> var y = 3;<br /> var g = function(){<br /> var x = 2+ y;<br /> ...<br /> }<br />}<br />E se a função interna durar mais que a função externa?<br />
  26. 26. Closures<br />Quando a função interna dura mais que a externa, o escopo externo é preservado<br />Isso se chama closure<br />
  27. 27. Um closure simples<br />var f = function(x){<br /> var m = function(y){<br />returnx * y; <br />}<br />return m;<br />}<br />var dobro = f(2);<br />var triplo = f(3);<br />alert(dobro(10));<br />alert(triplo(10));<br />Quando f() é executado, um novo m() é criado<br />Enquanto m() existir, seu escopo existe, e o do seu ‘pai’ também<br />
  28. 28. Usando closures<br />InformationHiding<br />Funções com timers<br />Eventhandlers<br />Callbacks<br />
  29. 29. Clojures: Dados privados <br />var quo = function (status) {<br />return {<br />get_status: function ( ) {<br />return status;<br /> }<br /> };<br />};<br />var myQuo = quo("amazed");<br />alert(myQuo.get_status( ));<br />
  30. 30. Closures: timers<br />var fade = function (node) {<br /> var level = 1;<br /> var step = function ( ) {<br /> var hex = level.toString(16);<br />node.style.backgroundColor = '#FFFF' + hex + hex;<br />if (level < 15) {<br />level += 1;<br />setTimeout(step, 100);<br /> }<br /> };<br />setTimeout(step, 100);<br />};<br />fade(document.body);<br />
  31. 31. Closure: eventhandler<br />Função que adiciona um eventhandler para uma lista de nodes.<br />Ao clicar, alerta a ordem do nó.<br />var add_the_handlers = function (nodes) {<br /> var i;<br /> for (i = 0; i < nodes.length; i += 1) {<br />nodes[i].onclick = function (e) {<br />alert(i);<br /> }<br /> }<br />};<br />Qual o resultado? <br />
  32. 32. Closure: eventhandler<br />Exemplo correto<br />var add_the_handlers = function (nodes) {<br /> var i;<br /> for (i = 0; i < nodes.length; i += 1) {<br />nodes[i].onclick = function (i) {<br />returnfunction (e) {<br />alert(i);<br /> };<br />} (i);<br /> }<br />};<br />
  33. 33. Curry<br />
  34. 34. Curry<br />Funções são valores<br />É possível combinar uma função com alguns argumentos e produzir outra função<br />var mult = function (a, b) {return a * b};<br />var duplicar = mult.curry(2);<br />var duplicar = function (b){ retunr 2*b};<br />
  35. 35. Função curry<br />Curry cria um closure queguarda a função original e seusargumentospararealizar o currying<br />Quandoexecutada, elaretorna o resultadodafunção original com osargumentospassadosao curry e ospassados a ela<br />var mult = function (a, b) {return a * b};<br />var duplicar = mult.curry(2);<br />varseis = duplicar(3); //mult.curry(2)(3) >>> 6<br />
  36. 36. Function.prototype.curry = function ( ) {<br />varargs = arguments, that = this;<br /> return function ( ) {<br /> return that.apply(null, args.concat(arguments));<br /> };<br />}); //PROBLEMA: arguments não é um array<br />
  37. 37. Função curry: final<br />Function.prototype.curry = function( ) {<br /> var slice = Array.prototype.slice,<br />args = slice.apply(arguments),<br />that = this;<br />returnfunction ( ) {<br />returnthat.apply(null, args.concat(slice.apply(arguments)));<br /> };<br />});<br />
  38. 38. Closures: callbacks<br />var replace = function (el, url){<br /> var callback = function(t){<br />el.innerHTML = t;<br /> };<br />makeXHR(callback, url); // ajax<br />}<br />replace (myEl, minhaURL);<br />
  39. 39. Closures: cuidados<br />Evite criar funções em loops<br />Para evitar closures indesejados<br />Atenção com o this<br />Mais sobre isso com bind<br />
  40. 40. bind<br />
  41. 41. This<br />window.name= "thewindowobject"<br />functionscopeTest() {<br />returnthis.name<br />}<br />scopeTest()<br />// -> "thewindowobject"<br />var foo = {<br />name: "thefooobject!",<br />otherScopeTest: function() { returnthis.name }<br />}<br />foo.otherScopeTest()<br />// -> "thefooobject!"<br />
  42. 42. Javascript é dinâmica<br />//atribuindo a função, SEM executá-la<br />window.test= foo.otherScopeTest<br />//chamando a função<br />test() ; // -> "the window object" <br />
  43. 43. Functionbind<br />Eu gostaria de escolher o ‘this’ da minha função<br />window.test = foo.otherScopeTest.bind(foo);<br />test() // -> "thefooobject!"<br />Function.prototype.bind = function(scope) {<br /> var _function = this;<br />returnfunction() {<br />return _function.apply(scope, arguments);<br /> }<br />}<br />
  44. 44. Partes Feias<br />Ricardo Cavalcanti<br />kvalcanti@gmail.com<br />
  45. 45. Variáveis globais<br />Todas as coisas são carregadas no mesmo objeto global<br />var foo = value;<br />window.foo = value;<br />foo=value;<br />
  46. 46. Escopo<br />Apesar da sintaxe de C<br />Blocos não criam escopo<br />O escopo é sempre da função<br />
  47. 47. Inserção de ;<br />Há um mecanismo de completar com ; alguns comandos<br />return ;<br />{ <br />status: true<br />};<br />return<br />{ <br />status: true<br />};<br />=<br />return { <br />status: true<br />};<br />
  48. 48. Palavras reservadas<br />abstract booleanbreak byte case catch charclassconst continue debugger default delete do doubleelseenumexportextendsfalse final finallyfloat for functiongotoifimplementsimport in instanceofint interface longnativenewnull package privateprotectedpublicreturn short static super switch synchronizedthisthrowthrowstransienttruetrytypeof var volatilevoidwhilewith<br />var method; // ok<br />var class; // illegal<br />object = {box: value}; // ok<br />object = {case: value}; // illegal<br />object = {'case': value}; // ok<br />object.box = value; // ok<br />object.case = value; // illegal<br />object['case'] = value; // ok<br />
  49. 49. Unicode<br />char em Javascript tem 16bits<br />Um charunicode são 2 caracteres em javascript<br />
  50. 50. typeof<br />typeof 98.6 >> ‘number’<br />typeofnull >> ‘object’ <br />my_value === null //melhor<br />if (my_value && typeofmy_value === 'object') { <br /> // my_value is an object or an array! <br />}<br />typeof /a/ >> ‘object’ ou ‘function’ <br />depende da implementação<br />
  51. 51. parseInt<br />Converte um string num integer<br />Para quando vê um não-dígito<br />parseInt("16") >> 16<br />parseInt("16 mil") >> 16<br />Se o string começar com 0 é utilizada a base 8<br />parseInt("08") >> 0<br />parseInt("09") >> 0<br />Parse int pode receber a base<br />parseInt("08", 10) >> 8<br />
  52. 52. Ponto fllutuante<br />Javascript usa IEEE Standard for Binary Floating-Point Arithmetic (IEEE 754)<br />Portanto<br />0.1 + 0.2 !== 0.3<br />Atenção quando utilizar valores monetários<br />Melhor multiplicar por 100<br />
  53. 53. NaN<br />Se algum operando for NaN, o resultado da operação será NaN<br />Converter um string em inteiro gera NaN<br />Porém<br />NaN === NaN // false<br />Use a função isNaN<br />isNaN(NaN) // true<br />
  54. 54. null e undefined<br />value = myObject[name]; <br />if (value == null) { <br /> alert(name + ' not found.'); <br />}<br />Um erroanula o outro!<br />value é undefined, mas o operador == faz o type coersion<br />Cuidado: NaN e undefined sãovariáveisglobais! <br />
  55. 55. Partes ruins<br />
  56. 56. ==<br />'' == '0' // false<br />0 == '' // true<br />0 == '0' // true<br />false == 'false' // false<br />false == '0' // true<br />false == undefined // false<br />false == null // false<br />null == undefined // true<br />' ' == 0 // true<br />
  57. 57. with<br />Para acessar os atributos de um objeto<br />Problemas:<br />with (obj) {<br /> a = b; <br />}<br />O mesmo que<br />if (obj.a === undefined) {<br /> a = obj.b === undefined ? b : obj.b;<br />} else {<br />obj.a = obj.b === undefined ? b : obj.b;<br />}<br />
  58. 58. eval<br />Evite!<br />Bem como outras formas que recebem código como string<br />Contrutor de Fuction<br />setTimeout<br />setInterval<br />Problema de segurança<br />Difícil de checar e de ler<br />
  59. 59. switch FallThrough<br />Switch-case sem break<br />Fonte de muitos erros, cuidado!<br />
  60. 60. Comandos sem bloco<br />Sempre use blocos nos comandos<br />if (ok)<br /> t = true;<br />if (ok)<br /> t = true;<br /> advance( );<br />vira<br />if (ok) {<br /> t = true;<br /> advance( );<br />}<br />parece<br />if (ok) {<br /> t = true;<br />}<br />advance( );<br />Mas naverdade é<br />
  61. 61. Operadores de bits<br />Os mesmos de java<br />& and<br />| or<br />^ xor<br />~ not<br />>> signed right shift<br />>>> unsigned right shift<br /><< left shift<br />Convertem para integer e desconvertem<br />Longe do hardware, lentos<br />
  62. 62. TypedWrappers<br />Desnecessários<br />newBoolean(false)<br />Evite o uso de newBoolean, newNumber, new String<br />Também evite newObject e newArray<br />Use {} e []<br />
  63. 63. Para evitar erros<br />
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×