Objetos em Javascript - Parte 2

Victor Feitosa
Training Center
Published in
4 min readMay 21, 2017

Esse post é o segundo post de uma série de posts sobre a minha jornada de aprendizado. Ele não tem pretensão de ser um tutorial, mas apenas um pequeno registro do que eu aprendo todos os dias. Você pode acompanhar o primeiro aqui.

Estou aprendendo Javascript, pois quero me tornar um Desenvolvedor Web. Tenho noções básicas de coisas que aprendi na faculdade, como C, C++, Python e um pouco do paradigma de orientação a objetos. O que me motivou a começar a escrever foi um vídeo que chegou até mim pelo Training Center.
O que estou utilizando atualmente como ferramenta para estudar são os exercícios e desafios do FreeCodeCamp, além de utilizar o livro Eloquent Javascript, sobre o qual vou falar agora.

Prototype Interference

Os prototypes podem ser utilizados para adicionar novas propriedades e métodos para todas as instâncias do objeto. Só que isso pode nos causar alguns probleminhas:
No capítulo anterior, o autor cria objetos como uma forma de associar valores com nomes, numa espécia de lista:

Podemos usar um for/in loop para checar se um nome está lá.
E é ai que começam algumas incoveniências:

Não deveríamos ter uma propriedade nonsense pro nosso map e muito menos uma propriedade toString. E agora? Perceba que o nosso loop não retornou o toString como um método. Só obtivemos ele na segunda vez utilizando o in. Estranho, não? E isso acontece porque o Javascript faz uma distinção entre enumarable e nonenumarable properties.

As propriedades que criamos simplesmente associando coisas são enumarable. As propriedades padrões do Object.prototype são nonenumarable, e é por isso que elas não aparecem no loop for/in.
E se eu quiser criar minha propriedade nonenumarable property?
É bem simples: É só utilizar Object.defineProperty. No exemplo do livro:

Perceba como funciona o defineProperty: O objeto Object.prototype recebe a property hiddenNonsense cujo o valor é “hi” e o enumarable é falso, ou seja, torna-a nonenumarable. Perceba também que a property não aparece mais no loop for/in.

Um problema, nesse caso, é que se fizermos:

Ainda teremos que hiddenNonsense está no objeto map.
Uma solução para isso é usar o método hasOwnProperty():

Agora sim! Esse hasOwnProperty nos diz se o objeto tem a property, sem olhar para nenhum dos seus prototypes.

Prototype-less objects

Indo um pouquinho mais fundo: Imagine que você quer criar um método que já existe, como o hasOwnProperty e quer definir o resultado disso como 42.
Nesses casos, ter um prototype só nos atrapalha, pois os nossos objetos funcionam mais como uma lista. O que podemos fazer sobre isso?
Simples: criar um objeto sem prototype! Pois um objeto sem prototype não terá esses métodos nativos do Object.Prototype.

E como fazemos isso? Passamos null como prototype do objeto!

Legal, né? Agora você nem precisa mais da “gambiarra” do hasOwnProperty porque todos os métodos que ele tiver serão os do próprio objeto!

Polymorphism

Polymorphism nada mais é do que um mesmo método funcionar de forma diferente para diferentes tipos de coisas.
Por exemplo: lembra que o método ToString funciona de forma diferente para arrays e para números?
Isso é um exemplo de Polymorphism!

Getters e Setters

Imagine que você tem o seguinte construtor:

Aqui eu crio um construtor que recebe dois parâmetros: firstName e lastName e usa esses valores para criar o FullName da pessoa. O problema neste exemplo é que se eu mudo o um dos nomes, o fullName não muda.

E é aí que entram nossos Getters e Setters!
Getters e Setters são maneiras de ler e mudar as propriedades de um objeto. Elas funcionam como uma espécie de atalho para isso. O get associa uma propriedade de um objeto a uma função que será chamada sempre que tal propriedade é acessada.

No código acima, construímos nosso get com o Object.defineProperty. A nossa função fullName vai ser chamada sempre que a propriedade for acessada. Quando você chamar a propriedade fullName, ele vai acessar os valores do firstName e lastName e retornar o valor baseado neles. Por isso quando mudamos um dos dois parâmetros, o nosso fullName também muda.

E se não quisermos que o usuário mude o valor do fullName quando ele quiser? É para isso que o nosso setter serve: ele vai ser chamado sempre que alguém tenta mudar o valor da propriedade. Se criarmos um getter sem um setter, qualquer tentativa de mudar a propriedade do objeto.

Vou parar por aqui e tentar trazer mais exemplos de getters e setters no próximo artigo :)

Continue acompanhando

Espero que você tenha curtido. Qualquer sugestão e/ou críticas, só falar :)
Continue seguindo o meu trajeto, vou tentar fazer posts novos todas semanas(menos em épocas de prova hahaha).

Se você ainda não conhece o Training Center, de uma olhada nesse artigo.

Se curtiu essa dica, da um like aqui no Medium e compartilhe esse post nas redes sociais.

--

--