A orientação a objetos de JS é bem peculiar. Dois aspectos são fundamentais. Primeiro, JS tem um conceito simples de objeto definido como uma coleção dinâmica de propriedades (ou membros) que, por sua vez, são pares nome-valor, em que cada nome é uma string e cada valor é um dado de qualquer um dos tipos válidos da linguagem. Segundo, JavaScript tem uma excelente notação literal para descrever objetos que é ao mesmo tempo simples, consisa e poderosa.
Esta notação é tão boa que é a origem da famosa notação JSON que significa, literalmente, JavaScript Object Notation, e que é a língua franca para a comunicação entre sistemas (e nem é mais restrito apenas à web).
turmas1a.js
mostra como é possível criar
objetos sem a necessidade de classes. A função
create_turma
é o que se chama de uma função factory: uma
função simples que cria um objeto e que o retorna. Graças à
notação literal de objetos de JavaScript o código para
funções desse tipo pode ser bastante simples e legível. Leia
o código. Acho que dispensa explicações. Observe que o
último log
registra que os dois métodos matricula
são
diferentes (dois objetos diferentes na memória, portanto).
turmas1b.js
difere do primeiro exemplo
apenas pela escrita em um estilo mais parecido com Java (em
que o uso da notação literal de objetos é reduzida ao uso do
operador dot para definir os membros do objeto. O último
log
também registra que os dois métodos são duas
funções/objetos diferentes na memória, demonstrando que as
duas versões são idênticas em termos de efeitos.
turmas2a.js
usa o estilo popularizado por
versões antigas de JavaScript para a escrita do design
pattern que implementa uma classe sobre funções. Observe
que aqui uso apenas um elemento introduzido em JavaScript
especificamente pra facilitar a implementação desse
pattern: o operador new
pra invocar a função Turma
que será usada como construtor.
turmas2b.js
estende o exemplo anterior e
introduz mais uma facilidade de JavaScript pra facilitar a
implementação do pattern de classe: o membro prototype
de
funções usadas como construtores, que é usado para registrar
métodos no objeto protótipo que será compartilhado por todas as
instâncias criadas quando a função é invocada via o operador
new
. O uso de prototype
permite criar e usar um único método
matricula
compartilhado pelas instâncias. Você pode confirmar
isso, observando a saída do último log
do script.
turmas3.js
esta última versão introduz a versão
em que usamos a terceira (e melhor) facilidade de JavaScript para
a implementação do pattern de class: a palavra-chave class
.
Ela é usada para reunir em um único trecho do código fonte, a
declaração das funções que compõem a classe: o construtor e os
métodos. A sintaxe é bastante simples: usamos a palavra-chave
constructor
e a notação para descrever os parâmetros formais e
o corpo de funções pra definir o construtor; e sintaxe semelhante
para cada um dos métodos, usando o nome do método ao invés da
palavra-chave constructor
. A semântica, contudo, continua sendo
a do mesmo design pattern já apresentado nos exemplos
anteriores. Se você entrar no shell do node ou no console do
browser e consultar o typeof
de classes, observará que classes
são, na verdade, funções. Da mesma forma, seus métodos são
funções colocadas no membro prototype
da função que dá nome à
classe.