Desmistificando Herança e
Prototypes no Javascript
Sempre esteve lá, ninguém sabia o porquê
$ whoami
/khaosdoctor
@_staticvoid
lsantos.me
developers@squidit.com.br
@khaosdoctor
trainingcenter.io
2018.abcdevelopers.org
Encapsulamento
Polimorfismo
Arrow functions
não vão funcionar
????????
Herança
Herança nos dá isso
Herança nos dá isso
De onde veio isso?
De onde as coisas vem?
Tipos originais
De onde tudo aparece
Array()
Function()
Object()
String
Number
Object
Array
Func
RegExp
Como elas
funcionam?
__proto__
Nunca toque no __proto__
Object.Prototype
Não. Não é a mesma coisa
Prototype é um objeto de propriedades
O famoso “new”
Instâncias
Instâncias
Instâncias
Instâncias
Instâncias
Herança!
Herança Prototípica
Herança Prototípica
Instâncias
Cadeias de protótipos
Como eu sei o que eu quero?
Cadeias de protótipos
Cadeias de protótipos
Cadeias de protótipos
Cadeia de protótipos
Cadeia de protótipos
Cadeias de protótipos: a prática
O fim da cadeia
O fim da cadeia?
E o “extends”?
Extends
Extends
Extends: Exemplo
Extends
O que eu faço
com isso?
1. Métodos globais
2. Overload
2. Overload - Os problemas
3. Performance
3. Performance
.print
3. Performance
3. Performance
Referências
- bit.ly/medium-prototypes
- bit.ly/ecma-proto
- mzl.la/mdn-proto
- mzl.la/function-js
- mzl.la/extends-jsx
- bit.ly/encapsulamento-js
- bit.ly/polimorfismo-js
- bit.ly/this-js
/khaosdoctor @_staticvoidlsantos.me @khaosdoctor

[JS EXPERIENCE 2018] Desmistificando herança e prototypes no Javascript - Lucas Santos, Squid

Notas do Editor

  • #5 Quando falamos de Prototypes estamos falando diretamente de Herança, um dos pilares da orientação a objetos. Terminar com QUAIS SÃO OS PILARES DA ORIENTAÇÃO A OBJETOS?
  • #6 O primeiro pilar, tem uma definição formal mas basicamente é a capacidade de restringir acesso a métodos e propriedades, não é bonito no JS mas é possível
  • #7 Um exemplo seria encapsular um nome, no Javascript brincamos muito com o contexto para fazer isso possível
  • #8 O Javascript não possui o encapsulamento nativo
  • #9 O segundo pilar, possibilidade de objetos compartilharem comportamentos e sobrescreverem esses comportamentos de acordo com a necessidade
  • #10 Para falar disso vamos ter que notar duas coisas
  • #11 Arrow functions vão trocar o contexto para o contexto imediatamente superior (no nosso caso, Window) e esse contexto não tem os atributos, vai dar undefined em tudo
  • #12 O que é isso?
  • #13 Agora estamos chegando aonde queremos. O terceiro pilar, capacidade de objetos acessarem propriedades de outros objetos sem instancia-los
  • #14 A herança é o que permite que utilizemos métodos específicos de um Array sem que a gente tenha implementado eles.
  • #15 Nunca definimos nenhuma propriedade Map, ela deve estar vindo de algum lugar
  • #16 Essa é uma pergunta que a gente deveria fazer mais.
  • #17 Você já se perguntou quais são os tipos básicos do Javascript? O Javascript tem 3 tipos base de onde a maioria das coisas são geradas: O Array, o Object e o Function
  • #18 Quando criamos arrays, a notação literal é igual a notação de classe, e tudo isso vem de um objeto global Array
  • #19 O mesmo vale para funções
  • #20 Para objetos, a coisa é um pouco diferente, visto que se você colocar uma string em um new Object ele dará uma string com todas as propriedades da string
  • #21 Isto acontece porque TUDO deriva de Object, dependendo do parâmetro passado. Os contrutores são apenas funções que chamam new Object() e ele devolve valores baseados nos tipos primitivos
  • #23 Como esse objeto funciona? Como podemos usar uma função em um array e não em uma string?
  • #24 A questão é, como eu posso fazer .map em um array mas não em uma string?
  • #25 o dunder proto é uma implementação não oficial que foi criada para colocar as implementações do JS para cada navegador. É a referencia para o objeto acima da cadeia, enquanto o prototype é a referencia par ao objeto atual. Terminar com “Então é daí que vem a herança? O que a gente faz com isso?”
  • #26 Não podemos mexer nisso porque é um objeto de referência para outro objeto, alterar suas propriedade vai alterar a propriedade global do objeto no JS, ele foi criado só para questões de compatibilidade
  • #27 O __proto__ é referencia para outro objeto diferente, que é o prototype do objeto superior, onde de fato as implementações estão
  • #28 O objeto prototype só existe em funções para os casos quando você quer usar essas funções como construtores com o new
  • #29 E o que é o new então?
  • #30 Vamos imaginar que temos o mesmo código de antes e vamos criar uma instancia dessa função
  • #31 Quando usamos new, um objeto vazio é criado e colocado em prototype, depois ele é associado ao this e, por consequencia, o this.__proto__ é o Object.prototype (porque o this é um objeto)
  • #32 Se printarmos o prototype da instancia, ele será undefined, porque a instancia não é uma função e não pode ser usado como construtor
  • #33 Mas se printarmos o prototype do construtor, ele existe
  • #34 E se usarmos o __proto__ ele vai apontar para o prototype da funçao acima
  • #36 Dar definição de herança prototípica falando da forma de bolo, que você tem alguma coisa que pode virar o bolo mas vc precisa de uma forma para aquilo Da mesma forma criar um array vai colocar o objeto em uma “forma” de array com todas as propriedades
  • #37 Você pode fazer isso com qualquer tipo primitivo. Então como vamos usar essas propriedades? Como o JS sabe onde um método está?
  • #38 Herança no JS nada mais é do que uma propriedade passada entre objetos
  • #39 Analogia da escola: Imagine que você tem uma prova para fazer mas não tem caneta. Você pede para um amigo se ele tem uma caneta, mas ele também não tem, então ele pede para o amigo dele, e este amigo tem uma caneta que é passada para você.
  • #41 Na analogia, o __proto__ é como o JS sabe que você é amigo da outra pessoa e o prototype é o que você tem disponível
  • #42 Falar sobre a função hasOwnProperty que diz se o próprio objeto possui um método e não sua cadeia de protótipos PROXIMO SLIDE TEM O EXEMPLO
  • #43 O __proto__ sempre aponta para o prototype do objeto de cima da cadeia e o __proto__ deste aponta para o outro acima e assim vai
  • #44 Aqui é aonde a herança aparece, se chamarmos George.hello() vamos procurar o método em outro objeto que não é o nosso
  • #46 Fazer a pergunta: Se eu fizer isso para os Arrays e Functions, vou obter o mesmo resultado?
  • #47 Não, o Array e Function são construtores assim como todos os outros métodos String, Boolean e etc, eles tem a forma no Object
  • #48 E como o Extends funciona?
  • #49 Quando fazemos a notação de extends, essencialmente estamos dizendo que a classe filha é protótipo do pai
  • #50 Que é essencialmente isto que estamos fazendo
  • #51 Um exemplo com uma classe real
  • #52 Quando damos “class x extends null” criamos uma classe que não estende o Object.prototype
  • #55 Métodos que podem ser sobrescritos. A chave está na linha 7, aqui podemos usar o exemplo que Printer é o driver genérico enquanto Epson é o driver proprietário
  • #56 O problema com overloads é sobrescritas de objetos globais como Array e Object
  • #57 Fazer isso em sistemas grandes pode quebrar completamente tudo (dar exemplo do facebook) FALAR SOBRE O ARTIGO SMOOSHGATE
  • #58 Criar métodos locais criará cópias do mesmo método para todas as instancias do objeto. Dizer que TALVEZ NÃO SEJA O MELHOR EXEMPLO, falar sobre usuários
  • #59 Voltando para o que explicamos antes, o this é um objeto vazio que é criado todas as vezes
  • #60 O que fazemos aqui é instanciar 5 milhões de métodos print iguais em 5 milhões de objetos diferentes, cada um apontando para um endereço de memória, o que pode causar um memory leak
  • #61 O ganho não é tanto no tempo, mas sim na performance de memória