Para um melhor entendimento deste artigo, é necessário algum conhecimento sobre programação orientada a objetos, existem vários artigos na web e bons livros dedicados ao assunto. Tomemos como exemplo de objeto, um ventilador. Ao olharmos para este objeto, podemos identificá-lo dentre outros eletrodomésticos pelas suas características. Outros ventiladores podem apresentar características idênticas, porém são objetos distintos. Um ventilador pode estar desligado ou ligado em algumas velocidades. Detalhes de sua estrutura ficam ocultos internamente, pois não precisamos conhecê-los para fazer uso do mesmo.
Javascript difere-se de linguagens clássicas orientadas a objeto como Java e C++ principalmente por não possuir uma definição formal de classe. Entretanto possui seu próprio tipo de herança baseada em protótipo e faz uso constante de objetos baseando-se nesse tipo de herança.
Função construtora e propriedades / Classe e atributos
Na programação orientada a objetos, é comum utilizar tipos de objetos (classes) personalizados. Essas classes1 são úteis em diversos casos, por exemplo, se seu programa manipula várias formas geométricas, poderiam haver várias classes de objetos como quadrados, retângulos e círculos. Utilizando nosso exemplo, vamos criar a função construtora Ventilador, contendo as propriedades2 velocidadeMaxima e ligado. Observe que a propriedade velocidadeMaxima recebe o valor do argumento velMax.
function Ventilador(velMax) { this.velocidadeMaxima = velMax; this.ligado = false; }
A palavra-chave this
é responsável por iniciar o objeto adequadamente.
Instâncias
A criação de um objeto, ou seja, a instanciação de uma classe é realizada com uso do operador new
. Após este operador vem o nome da função construtora, responsável pela inicialização do objeto.
Alguns exemplos de instanciação:
var obj = new Object(); var data = new Date();
Seguindo mais uma vez o exemplo do ventilador:
var ventilador1 = new Ventilador(3);
Acessando propriedades
Para acessar as propriedades de um objeto você deve utilizar o operador “.
” que deve ser precedido de uma referência ao objeto e sucedido pelo nome de uma de suas propriedades.
console.log(ventilador1.velocidadeMaxima); // Retorna 3
Diferente das linguagens clássicas orientadas a objeto, Javascript permite que propriedades sejam adicionadas a qualquer momento durante a execução do código. Por exemplo, vamos adicionar a propriedade cor a nosso ventilador:
ventilador1.cor = "branco"; console.log(ventilador1.cor); // Retorna branco
Métodos
Métodos em Javascript são funções invocadas por objetos. Para criar um novo método, basta atribuir uma função a um nome no objeto utilizando também o operador “.
” como ocorre com as propriedades. O exemplo abaixo demonstra como definir o método ligar para a classe Ventilador utilizando a função liga através da propriedade prototype
.
function liga() { this.ligado = true; } Ventilador.prototype.ligar = liga;
Caso queira adicionar um método a um objeto em particular, pode fazê-lo da seguinte maneira:
ventilador2 = new Ventilador(2); ventilador2.ligar = liga;
Outro uso possível é definir o método na estrutura da classe:
function liga() { this.ligado = true; } function Ventilador(velMax) { this.velocidadeMaxima = velMax; this.ligado = false; this.ligar = liga; }
A palavra chave this
é substituída pelo objeto que invoca a função, essa é uma das principais vantagens da utilização de métodos. Exemplo de uso:
var ventilador = new Ventilador(3); console.log(ventilador.ligado); // Retorna false ventilador.ligar(); console.log(ventilador.ligado); // Retorna true
Literais de objeto
Os literais de objeto3 possibilitam criar e iniciar objetos de uma maneira diferente. A sintaxe é definida por uma lista de pares nome/valor separados por vírgulas entre um par de chaves. Cada par nome/valor é definido pelo nome da propriedade seguido de dois pontos e do valor correspondente.
var Livro = { titulo : "Os Três Mosqueteiros", autor : "Alexandre Dumas", capitulo1 : { titulo : "Os três presentes do sr. D'Artagnan pai", paginas : 11 }, capitulo2 : { titulo : "A antecâmara do sr. Tréville", paginas : 8 } } // Acessando as propriedades: console.log(Livro.titulo + " - " + Livro.autor + "\\n\\t" + Livro.capitulo1.titulo + " - " + Livro.capitulo1.paginas + " páginas\\n\\t" + Livro.capitulo2.titulo + " - " + Livro.capitulo2.paginas + " páginas");
Composição
A composição é um recurso utilizado para definir uma relação do tipo “tem um” (“has a” relationship), ou seja, um objeto que conta com outros objetos para formar sua estrutura. Por exemplo, um objeto do tipo Carro teria em sua estrutura objetos do tipo Roda, Volante, Banco. O exemplo anterior que descreve um livro, também demonstra o uso deste recurso.
function Livro(titulo, autor) { this.titulo = titulo; this.autor = autor; } function Capitulo(titulo, paginas) { this.titulo = titulo; this.paginas = paginas; } var livro = new Livro("Os Três Mosqueteiros", "Alexandre Dumas"); var capitulo1 = new Capitulo("Os três presentes do sr. D'Artagnan pai", 11); var capitulo2 = new Capitulo("A antecâmara do sr. Tréville", 8); // Os objetos do tipo Capitulo fazem parte da composição do objeto livro livro.capitulo1 = capitulo1; livro.capitulo2 = capitulo2; // Acessando as propriedades: console.log(livro.titulo + " - " + livro.autor + "\\n\\t" + livro.capitulo1.titulo + " - " + livro.capitulo1.paginas + " páginas\\n\\t" + livro.capitulo2.titulo + " - " + livro.capitulo2.paginas + " páginas");
Encapsulamento
Como exposto no início do artigo, em nosso exemplo que representa um ventilador, detalhes da estrutura de alguns objetos ficam ocultos internamente, pois não precisamos conhecê-los para fazer uso dos mesmos. O encapsulamento tem por objetivo esconder essa informação que não precisa ser de conhecimento do utilizador da classe. Seu uso é uma boa prática quanto à manutenção da classe, pois podemos modificar a parte que é oculta ao utilizador sem alterar sua forma de implementação. Em Javascript podemos usar encapsulamento em propriedades de uma classe utilizando a palavra-chave var
ao invés da palavra-chave this
e do operador “.
”.
function Ventilador(velMax) { var maximaPermitida = 5; // Uso de encapsulamento var velocidadePadrao = 3; // Variáveis privadas // Avalia se a velocidade máxima fornecida é maior que zero e menor que 5, o limite atual. if (velMax > 0 && velMax <= maximaPermitida) { // Caso seja, atribui o valor fornecido à propriedade velocidadeMaxima this.velocidadeMaxima = velMax; } else { // Caso contrário, atribui o valor da variável velocidadePadrao à propriedade velocidadeMaxima this.velocidadeMaxima = velocidadePadrao; } this.ligado = false; this.ligar = function() { // O método ligar agora é definido this.ligado = true; // por um literal de função, o que } // melhora a legibilidade do código. } ventilador = new Ventilador(0); // Cria a instância fornecendo o valor 0 para o argumento velMax; console.log(ventilador.velocidadeMaxima); // Retorna 3 – o padrão console.log(ventilador.maximaPermitida); // Retorna undefined
Herança
Em Javascript a herança ocorre por meio de objetos protótipos4 e define uma relação do tipo “é um” (“is a” relationship). Cada objeto herda propriedades e métodos de seu objeto protótipo que é referenciado pela propriedade prototype
. A classe Object
é a superclasse de todas as classes definidas em Javascript, ou seja, todos os construtores criados herdam propriedades e métodos definidos no construtor Object()
como por exemplo o método toString()
, que assim como outros pode ser sobrescrito na subclasse. Em alguns casos, é conveniente utilizar este recurso em classes personalizadas, para isso basta definir um construtor como valor para a propriedade prototype
da classe em questão. Como exemplo simplório, vamos definir a classe Eletrodomestico com a propriedade ligado e os métodos ligar e desligar comuns a todos os eletrodomésticos e então definir a classe Ventilador com propriedades e métodos peculiares.
function Eletrodomestico() { this.ligado = false; this.ligar = function() { this.ligado = true; } this.desligar = function() { this.ligado = false; } } function Ventilador(velMax) { var maximaPermitida = 5; // Uso de encapsulamento var velocidadePadrao = 3; // Variáveis privadas if (velMax > 0 && velMax <= maximaPermitida) { this.velocidadeMaxima = velMax; } else { this.velocidadeMaxima = velocidadePadrao; } } Ventilador.prototype = new Eletrodomestico(); // Define o objeto protótipo ventilador = new Ventilador(4); console.log(ventilador.ligado); // Retorna false ventilador.ligar(); console.log(ventilador.ligado); // Retorna true
A utilização do objeto protótipo faz com que a propriedade constructor
também seja herdada da superclasse, o que definiria a classe Eletrodomestico como valor da propriedade no objeto ventilador. Uma alternativa é definir de forma explícita a propriedade constructor
:
Ventilador.prototype.constructor = Ventilador;
Conclusão
Este artigo é apenas um incentivo à adoção dos conceitos da orientação a objetos em Javascript. Com o entendimento dos conceitos, os desenvolvedores podem corroborar as vantagens em códigos mais complexos, organizando o desenvolvimento e facilitando a manutenção dos scripts.
Notas
1. Termo usado informalmente no artigo.
2. Nas linguagens clássicas orientadas a objeto, geralmente usa-se o termo atributo ou campo.
3. Conhecidos também como inicializadores de objetos ou objetos literais, implementados a partir de Javascript 1.2.
4. Implementados a partir de Javascript 1.1.
Informações Sobre o Documento Original
- Autor: Leandro Mercês Xavier
- Última Atualização: 09/05/2007
- Informações sobre Copyright: Este artigo está disponível sob os termos da Creative Commons Atribuição-Compartilhamento pela mesma licença 2.5 Brasil
Categorias
Interwiki Language Links