Este documento discute conceitos de programação orientada a objetos em Javascript para desenvolvedores acostumados com C#. Ele explica como Javascript lida com objetos dinâmicos, "classes", herança e outros conceitos usando o objeto prototype. O documento também mostra como simular classes abstratas e métodos de extensão usando prototype.
5. POO
Sumário
• Javascript não é orientado a objetos, mas podemos
força-lo a ser
• Objetos Dinâmicos
• “Classes”
• Prototype
• Herança
• Abstract
• Extensions Methods
6.
7. POO
Objetos Dinâmicos
• C# Suporta Inicializadores de objetos dinâmicos
//C#
var cliente = new Cliente()
{
Nome = "Thiago",
Companhia = "Academia do Programador",
DataFormatura = " 11/11/11",
Endereco = new Endereco()
{
Cidade = "Lages",
Estado = "SC",
Bairro = "Coral"
},
Apelidos = new List<Apelido>()
{
new Apelido("Thiago Jr"),
new Apelido("Juninho"),
new Apelido("Tio Sartas")
}
};
//C#
var cliente = new {
Nome = "Thiago",
Companhia = "Academia do Programador",
DataFormatura = " 11/11/11",
Endereco = new
{
Cidade = "Lages",
Estado = "SC",
Bairro = "Coral"
},
Apelidos = new[]
{
"Thiago Jr",
"Juninho",
"Tio Sartas",
}
};
cliente.novaPropriedade = "";
8. POO
Objetos Dinâmicos
• No Javascript, isso é natural
//Javascript
var cliente = {
Nome: "Thiago",
Companhia: "Academia do Programador",
'Data Formatura': "11/11/11",
Endereco: {
Cidade: "Lages",
Estado: "SC",
Bairro: "Coral“
},
Apelidos: [
"Thiago Jr",
"Juninho",
"Tio Sartas"
]
};
cliente.novaPropriedade = "";
9. POO
Objetos Dinâmicos
• Sintaxe Ponto
• Sintaxe Colchete
//Javascript
var nome = cliente.nome;
var nome2 = cliente["nome"];
var data = cliente. "Data Formatura";// Nope
var data2 = cliente["Data Formatura"];
var cidade = cliente.Endereco.Cidade;
var cidade2 = cliente["Endereco"]["Cidade"];
var cidade3 = cliente["Endereco"].Cidade;
cliente["Entrar de férias"] = function() {
return {"Dias tirados":20};
};
cliente["Entrar de férias"]();
var dias = cliente["Entrar de férias"]()["Dias tirados"];
12. POO
“Classes”
• No .NET, Classes são receitas bem definidas para criação
de objetos
• Containers para dados, código e comportamento
//C#
class Cliente {
string Nome { get; set; }
string Empresa { get; set; }
public Cliente(string nome, string empresa="")
{
Nome = nome;
Empresa = empresa;
}
}
13. POO
“Classes”
• No .NET, Classes são receitas bem definidas para criação
de objetos
• Containers para dados, código e comportamento
//C#
class Cliente {
string Nome { get; set; }
string Empresa { get; set; }
public Cliente(string nome, string empresa="")
{
Nome = nome;
Empresa = empresa;
}
}
//Javascript
function Cliente(nome, empresa) {
this.nome = nome;
this.empresa = empresa;
this.enviarEmail = function(email) { };
}
var c = new Cliente('Sonic', "SEGA");
c.enviarEmail("sonic@sega.com");
14. POO
“Classes”
• Mas tudo precisa ser público??
• Nope.. Closures servem para isso
//Javascript
function Cliente(nome,empresa) {
//public
this.nome = nome;
this.empresa = empresa;
//private
var mailServer = 'mail.google.com';
this.enviarEmail=function(email) {
endEmailViaServer(mailServer, email);
}
}
15. POO
“Classes”
• E propriedades?
• Sintaxe especial.. Use apenas se necessário
• Readonly?
//Javascript
function Cliente(nome) {
var _nome = nome;
this.empresa = empresa;
//{ get; set; }
Object.defineProperty(this, 'nome', {
get:function () { return "Mr. " + _nome; },
set:function(value) { _nome = value.toLowerCase(); }
});
}
16. POO
“Classes”
• Membros Estáticos
//Javascript
function Cliente(nome,empresa) {
this.nome = nome;
this.empresa = empresa;
}
Cliente.mailServer = 'mail.google.com';
var c = new Cliente();
var srv = c.mailServer; //nope
srv = Cliente.mailServer; //yep
17.
18. • Crie a classe Calculadora
• Ela terá todos os métodos convencionais, incluindo MOD
• (opcional) Use jQuery para relacionar eventos aos controladores
• Seu construtor recebe um nome que não pode ser alterado (somente
leitura) (ex: “Casio”)
• Crie a classe Operação(number, number, string operator)
• Antes de executar cada operação, salve num histórico
privado na calculadora
19.
20. Quiz
• O que essas chamadas irão logar?
function Cliente() {
var index = 1;
this.index = 2;
Object.defineProperty(this, "Index", {
get: function () { return index; }
})
}
Cliente.Index = 4;
var c = new Cliente();
console.log(c.Index);
console.log(c.index);
console.log(Cliente.index);
console.log(Cliente.Index);
21. Quiz
• O que essas chamadas irão logar?
function Cliente() {
var index = 1;
this.index = 2;
Object.defineProperty(this, "Index", {
get: function () { return index; }
})
}
Cliente.Index = 4;
var c = new Cliente();
console.log(c.Index);
console.log(c.index);
console.log(Cliente.index);
console.log(Cliente.Index);
//1
//2
//undefined
//4
22.
23. POO
O objeto Prototype
• Principal elo de correlação entre objetos em Javascript
• Cada objeto tem uma propriedade prototype
• É somente um objeto, e pode ter propriedades atribuídas nele
• Todas as propriedades de um “tipo” são compartilhadas entre
as instancias
24. POO
O objeto Prototype
//Javascript
function Animal(raca, comida) {
this.raca = raca;
this.comida = comida;
}
//Funciona mas não acessa dados privados
Animal.enviarEmail = function() {};
//Funciona e deixa acessar dados privados
Animal.prototype.enviarEmail=function(){
return this.raca+"@foo.baz"
}
var c = new Animal("Coelho");
log(c.raca); //Coelho
log(c.enviarEmail()); //Coelho@foo.baz
var c = new Animal("Vaca");
log(c.raca); //Vaca
log(c.enviarEmail()); //Vaca@foo.baz
function Animal(raca, comida) {
this.raca = raca;
this.comida = comida;
this.
}
enviarEmail=function(){
return this.raca+"@foo.baz"
}
Mas qual a diferença de fazer isso?
25. POO
Herança
function Animal(comida) {
this.comida = comida || "Nada";
}
Animal.prototype.comer=function(){
console.log( "comendo: "+this.comida);
};
var a = new Animal();
a.comer(); //"Comendo: nada“
log(a instanceof Animal); // true
function Coelho(cor){
this.cor=cor||"Branco";
}
//Automágica!
Coelho.prototype=new Animal("Legumes");
var c = new Coelho("Branco");
c.comer(); //"Comendo: legumes“
log(c instanceof Animal); //true
26. POO
Classe abstrata
var Animal = {
comida:'nada',
comer:function(){
log(this.comida)
}
}
function Coelho(cor){
this.cor=cor;
this.comida="legumes";
}
Coelho.prototype=Animal;
var c = new Coelho("Branco");
c.comer() //legumes
log(c instanceof Coelho); //true
log(c instanceof Animal) //error
27. POO
Extensions
• Prototype também pode ser usado para criar Extension
Methods
String.prototype.skipWords = function(qts) {
var split = this.split(' ');
var result = '';
for (i = qts; i < split.length; i += 1) {
result += split[i] + " ";
}
return result;
};
log("alguma string bem grande cheia de palavras".skipWords(4)); //"cheia de palavras“
28.
29. • Agora temos uma calculadora binária que herda da calculadora
convencional
• Todos os métodos antigos são postos em prototype
• Adicione métodos para converter e desconverter binários
• Adicione o método para converter para binário no protótipo da classe
String, para que possa ser usada dessa forma:
“400”.toBinary();
30. POO
Mais coisas de Classes
• Private
• Via closures e variáveis locais
• Protected
• Não suportado
• Sobrecarga de construtores
• Não, apenas sobrescrita de métodos
31. POO
E as interfaces?
• São desnecessárias
• Sinta-se confortável com DuckTyping
function Animal(comida){
this.comida= comida ||"nada";
this.mover=function(){};
}
function Carro(comb){
this.combustível=comb||"Diesel";
this.mover=function(){};
}
function mover(obj) {
obj.mover = obj.mover || function() {};
if(obj.mover)
obj.mover();
}
32.
33. Quiz
Atribuir um método ao prototype e atribuir ao this da classe tem a
mesma usabilidade
• Falso
• Verdadeiro
• Atribuirum método ao prototype e atribuir ao this da classe tem o
mesmo desempenho
• Verdadeiro
• Falso
34. Quiz
Atribuir um método ao prototype e atribuir ao this da classe tem a
mesma usabilidade
• Falso
• Verdadeiro
• Atribuirum método ao prototype e atribuir ao this da classe tem o
mesmo desempenho
• Verdadeiro
• Falso
36. Quiz
Quais os possíveis usos do prototype?
• Executar um trecho de código apenas uma vez,. E que seja usado por
todas as instancias
• Simular Herança e classe Abstrata
• Extension Methods
37. • Todos os objetos são dinâmicos
• Sintaxe colchete
• Classes
• Herança