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