OBS: este artigo é m artigo que encontrei em minhas pesquisas programação orientada a objetos e deixo bem claro que não sou eu quem o escrevi, achei um artigo importante para todos nós Devs.
Buscar
"
24 de abril de 2022 / #JavaScript
Programação orientada a objetos em JavaScript – explicada com exemplos
Artigo original escrito por Dillion Megida
Artigo original: Object Oriented Programming in JavaScript – Explained with Examples
Traduzido e adaptado por Daniel Rosa
JavaScript não é uma linguagem orientada a objetos e baseada em classes. Porém, ainda existem maneiras de se usar a programação orientada a objetos (POO, ou OOP - do inglês) com ela.
Neste tutorial, explicarei a POO e mostrarei como usá-la.
De acordo com a Wikipédia (texto em inglês), programação baseada em classes é
um estilo de Programação Orientada a Objetos (POO) em que a herança ocorre por meio da definição de classes de objetos, em vez de ocorrer por meio dos próprios objetos
O modelo mais popular de POO é o baseado em classes.
Porém, como eu mencionei, o JavaScript não é uma linguagem baseada em classes – é uma linguagem baseada em protótipos.
De acordo com a documentação da Mozilla:
Uma linguagem baseada em protótipos tem a noção de um objeto prototípico, um objeto usado como um modelo do qual obtemos as propriedades iniciais para um novo objeto.
Observe este código:
let names = { fname: "Dillion", lname: "Megida" } console.log(names.fname); console.log(names.hasOwnProperty("mname")); // Resultado esperado // Dillion // false
A variável de objeto names
tem apenas duas propriedades - fname
e lname
. Ela não tem métodos.
Então, de onde vem hasOwnProperty
?
Bem, ele vem do protótipo Object
.
Experimente colocar os conteúdos da variável no console:
console.log(names);
Quando expandimos os resultados no console, temos:
console.log(names)
Observe a última propriedade - __proto__
? Tente expandi-la:
A propriedade __proto__ de names
Você verá um conjunto de propriedades sob o construtor do Object
. Todas essas propriedades vêm do protótipo global de Object
. Se olhar atentamente, perceberá também nossa hasOwnProperty
oculta.
Em outras palavras, todos os objetos têm acesso ao protótipo de Object
. Eles não possuem essas propriedades, mas recebem acesso às propriedades pelo protótipo.
A propriedade __proto__
Ela aponta para o objeto que é usado como um protótipo.
Essa é a propriedade em todo objeto que lhe dá acesso à propriedade Object prototype
.
Todo objeto tem essa propriedade por padrão, que faz referência a Object Protoype
exceto quando configurado de outro modo (ou seja, quando o __proto__
do objeto é apontado para outro protótipo).
Modificando a propriedade __proto__
Essa propriedade pode ser modificada ao declarar explicitamente que ela deve fazer referência a outro protótipo. Os métodos a seguir são usados para se conseguir isso:
Object.create()
function DogObject(name, age) { let dog = Object.create(constructorObject); dog.name = name; dog.age = age; return dog; } let constructorObject = { speak: function(){ return "I am a dog" } } let bingo = DogObject("Bingo", 54); console.log(bingo);
No console, é isto que você verá:
console.log(bingo)
Consegue observar a propriedade __proto__
e o método speak
?
Object.create
usa o argumento passado para ele para se tornar o protótipo.
A palavra-chave new
function DogObject(name, age) { this.name = name; this.age = age; } DogObject.prototype.speak = function() { return "I am a dog"; } let john = new DogObject("John", 45);
A propriedade __proto__
de john
é direcionada para o protótipo de DogObject
. Lembre-se, no entanto, de que o protótipo de DogObject
é um objeto (para chave-valor). Por isso, ele também tem uma propriedade __proto__
que faz referência ao protótipo global de Object
.
Essa técnica é conhecida como ENCADEAMENTO DE PROTÓTIPOS.
Observe que a abordagem com a palavra-chave new
faz o mesmo que Object.create()
, mas facilita o processo, pois faz algumas coisas automaticamente por você.
Assim...
Todo objeto em Javascript tem acesso ao protótipo de Object
por padrão. Se for configurado para usar outro protótipo, por exemplo, prototype2
, então prototype2
também terá acesso ao protótipo de Object por padrão e assim por diante.
Combinação de objeto e função
Você provavelmente ficou confuso com o fato de DogObject
ser uma função (function DogObject(){}
) e ter propriedades que podem ser acessadas com uma notação ponto. Isso é conhecido como uma combinação de objeto e função.
Quando funções são declaradas, por padrão, elas recebem várias propriedades associadas a elas. Lembre-se de que funções também são objetos nos tipos de dados do JavaScript.
Por fim, as classes
O JavaScript introduziu a palavra-chave class
no ECMAScript 2015. Ela faz com que o JavaScript aparente ser uma linguagem de POO. Isso é, no entanto, apenas um adendo à sintaxe com relação à técnica de prototipação existente. A prototipação continua no segundo plano, mas faz o corpo externo parecer como se fosse POO. Veremos agora como isso é possível.
O exemplo a seguir é um uso geral de uma class
em JavaScript:
class Animals { constructor(name, specie) { this.name = name; this.specie = specie; } sing() { return `${this.name} can sing`; } dance() { return `${this.name} can dance`; } } let bingo = new Animals("Bingo", "Hairy"); console.log(bingo);
Esse é o resultado no console:
console.log(bingo)
__proto__
faz referência ao protótipo de Animals
(que, por sua vez, faz referência ao protótipo de Object
).
A partir disso, podemos ver que o construtor define os recursos principais enquanto tudo o que está fora do construtor (sing()
e dance()
) são os recursos adicionais (protótipos).
Em segundo plano, o uso da abordagem com a palavra-chave new
, o que vemos acima pode ser traduzido como:
function Animals(name, specie) { this.name = name; this.specie = specie; } Animals.prototype.sing = function(){ return `${this.name} can sing`; } Animals.prototype.dance = function() { return `${this.name} can dance`; } let Bingo = new Animals("Bingo", "Hairy");
Subclasses
Este é um recurso em POO onde uma classe herda recursos de uma classe pai, mas possui recursos adicionais que a classe pai não tem.
A ideia aqui é, por exemplo, criar uma classe cats. Em vez de criar a classe do zero - declarar as propriedades name, age e species do início, você herdará essas propriedades da classe pai animals.
A classe cats, então, pode ter propriedades adicionais como color of whiskers ('cor dos bigodes').
Vejamos como são feitas as subclasses com class
.
Aqui, precisamos de uma classe pai de onde a subclasse herdará. Examine o código abaixo:
class Animals { constructor(name, age) { this.name = name; this.age = age; } sing() { return `${this.name} can sing`; } dance() { return `${this.name} can dance`; } } class Cats extends Animals { constructor(name, age, whiskerColor) { super(name, age); this.whiskerColor = whiskerColor; } whiskers() { return `I have ${this.whiskerColor} whiskers`; } } let clara = new Cats("Clara", 33, "indigo");
Com o que temos acima, temos os seguintes resultados:
console.log(clara.sing()); console.log(clara.whiskers()); // Resultado esperado // "Clara can sing" // "I have indigo whiskers"
Ao colocar no console o conteúdo de clara, temos:
Você perceberá que clara
tem uma propriedade __proto__
que faz referência ao construtor de Cats
e tem acesso ao método whiskers()
. Essa propriedade __proto__
também tem uma propriedade __proto__
que faz referência ao construtor de Animals
, obtendo, assim, acesso a sing()
e dance()
. name
e age
são propriedades que existem em todos os objetos criados a partir daí.
Usando a abordagem com o método Object.create
, o que vemos acima se traduz assim:
function Animals(name, age) { let newAnimal = Object.create(animalConstructor); newAnimal.name = name; newAnimal.age = age; return newAnimal; } let animalConstructor = { sing: function() { return `${this.name} can sing`; }, dance: function() { return `${this.name} can dance`; } } function Cats(name, age, whiskerColor) { let newCat = Animals(name, age); Object.setPrototypeOf(newCat, catConstructor); newCat.whiskerColor = whiskerColor; return newCat; } let catConstructor = { whiskers() { return `I have ${this.whiskerColor} whiskers`; } } Object.setPrototypeOf(catConstructor, animalConstructor); const clara = Cats("Clara", 33, "purple"); clara.sing(); clara.whiskers(); // Resultado esperado // "Clara can sing" // "I have purple whiskers"
Object.setPrototypeOf
é um método que recebe dois argumentos - o objeto (primeiro argumento) e o protótipo desejado (segundo argumento).
A partir do que vemos acima, a função Animals
retorna um objeto com animalConstructor
como protótipo. A função Cats
retorna um objeto com catConstructor
como seu protótipo. catConstructor
, por outro lado, recebe o protótipo de animalConstructor
.
Portanto, animais comuns têm acesso apenas a animalConstructor
, mas gatos têm acesso a catConstructor
e a animalConstructor
.
Para encerrar
O JavaScript aproveita sua natureza prototípica para dar as boas-vindas aos desenvolvedores de POO ao seu ecossistema. Ele também fornece maneiras fáceis de criar protótipos e de organizar os dados relacionados.
Linguagens verdadeiramente de POO não realizam a prototipação em segundo plano - anote isso em algum lugar.
Obrigado a Will Sentance por seu curso na Frontend Masters - JavaScript: The Hard Parts of Object Oriented JavaScript (em inglês). Eu aprendi tudo o que você está vendo neste artigo (mais um pouquinho de pesquisa adicional) a partir desse curso. Você, com certeza, deve conferir.
Entre em contato comigo pelo meu Twitter, iamdillion, para fazer perguntas ou contribuições.
Obrigado pela leitura : )
Recursos úteis
- JavaScript orientado a objetos para iniciantes
- Introdução à Programação Orientada a Objetos em JavaScript (em inglês)
Daniel Rosa Um profissional dos idiomas humanos apaixonado por linguagens de computador. | A world languages professional in love with computer languages.
Se você leu até aqui, envie uma mensagem no Twitter para o autor para mostrar que você se importa com o trabalho.
Aprenda a programar gratuitamente. O plano de estudos em código aberto do freeCodeCamp já ajudou mais de 40.000 pessoas a obter empregos como desenvolvedores. Comece agora
O freeCodeCamp é uma organização sem fins lucrativos 501(c)(3), isenta de impostos e apoiada por doações (Número de identificação fiscal federal dos Estados Unidos: 82-0779546).
Nossa missão: ajudar as pessoas a aprender a programar de forma gratuita. Conseguimos isto criando milhares de vídeos, artigos e lições de programação interativas, todas disponíveis gratuitamente para o público. Também temos milhares de grupos de estudo do freeCodeCamp em todo o mundo.
As doações feitas ao freeCodeCamp vão para nossas iniciativas educacionais e ajudam a pagar servidores, serviços e a equipe.
Você pode fazer uma doação dedutível de impostos aqui.
Guias de tendências
Nova aba em HTML Máscaras de sub-rede 40 projetos em JavaScript Tutorial de button onClick Bot do Discord Centralizar em CSS Excluir pastas com o cmd Imagens em CSS 25 projetos em Python Excluir branches
Jogo do dinossauro Menu iniciar Arrays vazios em JS Caracteres especiais Python para iniciantes Provedores de e-mail 15 portfólios Node.js no Ubuntu 10 sites de desafios Clonar branches
Date now em JavaScript Var, let e const em JavaScript Axios em React ForEach em JavaScript Fotos do Instagram
Media queries do CSS Fix do Live Server no VS Code SQL em Python Interpretadas x compiladas Imagens SVG em HTML e CSS
Sobre Rede de ex-alunos Código aberto Loja Apoio Patrocinadores Honestidade Acadêmica Código de conduta Política de privacidade Termos de serviço Política de direitos de autor
"
Faça parte da nossa comunidade!
Domine as tecnologias utilizadas pelas empresas mais inovadoras do mundo e encare seu novo desafio profissional, evoluindo em comunidade com os melhores experts.