aprendendo orientação a objetos com javascript
TRANSCRIPT
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 1/117
1
ConteúdoCapítulo 1.......................................................................................................................................... 6
Objetos JavaScript ............................................................................................................................. 6
Criando Objetos............................................................................................................................. 6
Construtores JavaScript, Construção e Retorno de Instancias de Objetos ..................................... 11
Construtores de objetos nativos do JavaScript ............................................................................. 13
Funções Construtoras Não Nativas Definidas Pelo Usuário........................................................... 14
Instanciando Construtores Usando o Operador new .................................................................... 15
Criando Atalhos/Valores Literais a partir de Construtores ............................................................ 17
Valores Primitivos (Simples)......................................................................................................... 18
Os Valores Primitivos null, undefined, "string", 10, true, false, Não São Objetos .......................... 20
Como Valores Primitivos São Armazenados/Copiados no JavaScript ............................................ 21
Valores Primitivos São Igualados Pelo Valor ................................................................................. 22
Os Valores Primitivos String, Number, e Boolean Agem Como Objetos Quando Usados Como
Objetos........................................................................................................................................ 23
Valores Complexos (Compostos).................................................................................................. 24
Como Valores Complexos São Armazenados/Copiados no JavaScript ........................................... 26
Objetos Complexos São Igualados por Referência ........................................................................ 27Objetos Complexos Possuem Propriedades Dinâmicas................................................................. 27
O Operador typeof Usado em Valores Complexos e Primitivos .................................................... 28
Propriedades Dinâmicas Reservadas para Objetos Mutáveis ........................................................ 29
Todas as Instâncias Construtoras Possuem Propriedades Construtoras que Apontam para Suas
Funções Construtoras .................................................................................................................. 30
Verificar que um Objeto É uma Instância de uma Função Construtora Particular ......................... 33
Uma Instância Criada de um Construtor Pode Ter suas Propriedades Independentes (Propriedades
de Instância) ................................................................................................................................ 34
As Semânticas de "Objetos Javascript" e "Objetos Object()" ........................................................ 35
Capítulo 2........................................................................................................................................ 36
Trabalhando com Objetos e Propriedades........................................................................................ 36
Objetos Complexos Podem Conter a Maioria dos Valores e Propriedades do JavaScript .............. 36
Encapsulando Objetos Complexos em um Caminho Beneficamente Programático ....................... 38
Pegando/Configurando/Atualizando Propriedades de Objetos Usando a Notação de Ponto "." ou
Chaves "[]" .................................................................................................................................. 38
Deletando Propriedades do Objeto.............................................................................................. 41
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 2/117
2
Como Referências para Propriedades de Objetos são Resolvidas ................................................. 42
Usando hasOwnProperty, Verificar que uma Propriedade de Objeto Não é da Cadeia de Protótipo
.................................................................................................................................................... 44
Checando se um Objeto Contêm uma dada Propriedade Usando o Operador in .......................... 45
Enumerar Propriedades de Objetos Usando o Loop for.................................................................... 46
Objetos Host Contra Objetos Nativos........................................................................................... 47
Melhorando e Estendendo Objetos com Underscore.js................................................................ 48
Capítulo 3........................................................................................................................................ 50
Object() ........................................................................................................................................... 50
Visão Geral e Conceitual do Uso de Objetos Object() ................................................................... 50
Parâmetros Object() .................................................................................................................... 50
Propriedades e Métodos do Object() ........................................................................................... 51
Propriedades Instanciadas e Métodos do Objeto Object()............................................................ 52
Criando Objetos Object() Usando "Objetos Literais" .................................................................... 52
Todos os Objetos são Herdados do Object.prototype .................................................................. 54
Capítulo 4........................................................................................................................................ 54
Function()........................................................................................................................................ 54
Visão Conceitual Geral do Uso de Objetos Function()................................................................... 54
Parâmetros Function() ................................................................................................................. 55Propriedades e Métodos Function() ............................................................................................. 56
Instâncias de Propriedades e Métodos do Objeto Function.......................................................... 56
Funções Sempre Retornam um Valor ........................................................................................... 56
Funções são os Cidadãos de Primeira Classe (Não Apenas Sintaxe, mas Valores) ......................... 57
Passando Parâmetros para uma Função ...................................................................................... 58
Valores Disponíveis para Todas as Funções (this e arguments) ..................................................... 58
A Propriedade arguments.callee .................................................................................................. 59
Instância de Função, Propriedade length e arguments.length ...................................................... 59
Redefinindo Parâmetros de Função ............................................................................................. 60
Definindo uma Função (Sentença, Expressão, ou Construtor) ...................................................... 61
Invocando uma Função [Função, Método, Construtor, ou call() e apply()] .................................... 61
Funções Anônimas....................................................................................................................... 63
Função Expressão Auto-Invocada ................................................................................................ 63
Função Sentença Anônima Auto-Invocada ................................................................................... 63
Funções Podem Ser Aninhadas .................................................................................................... 64
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 3/117
3
Passando Funções para Funções e Retornando Funções de Funções ............................................ 64
Invocando Função Sentença Antes de Ser Definida (Levantamento de Função)............................ 65
Uma Função Pode Chamar a Si Mesma (Recursividade) ............................................................... 65
Capítulo 5........................................................................................................................................ 66
O Objeto Cabeça/Global .................................................................................................................. 66
Visão Geral do Conceito do Objeto Cabeça .................................................................................. 66
Funções Globais Contidas com o Objeto Cabeça .......................................................................... 67
O Objeto Cabeça Contra Propriedades Globais e Variáveis Globais .............................................. 67
Referenciando o Objeto Cabeça................................................................................................... 68
O Objeto Cabeça é Subentendido e Tipicamente Não Referenciado Explicitamente ..................... 69
Capítulo 6........................................................................................................................................ 69
A Palavra Chave this........................................................................................................................ 69
Visão Conceitual do this e Como Ele Refe para Objetos................................................................ 69
Como o Valor de this é Determinado? ......................................................................................... 71
A Palavra Chave this Refere-se ao Objeto Cabeça em Funções Aninhadas .................................... 72
Trabalhando em Torno da Questão da Função Aninhada Alavancando a Cadeia de Escopo .......... 73
Controlando o Valor de this Usando call() ou apply() ................................................................... 73
Usando a Palavra Chave this Dentro de Uma Função Construtora Definida por Usuário ............... 75
A Palavra Chave this Dentro de um Método com prototype Referencia para uma Instância doConstrutor ................................................................................................................................... 76
Capítulo 7 ........................................................................................................................................ 77
Escopo e Fechamentos..................................................................................................................... 77
Visão Conceitual de Escopo JavaScript ......................................................................................... 77
JavaScript Não Tem Escopo de Bloco ........................................................................................... 78
Usar var Dentro de Funções para Declarar Variáveis e Evitar Pegadinhas de Escopo .................... 78
A Cadeia de Escopo (Escopo Léxico) ............................................................................................. 79
A Cadeia de Escopo Retorna o Primeiro Valor Encontrado ........................................................... 80
Escopo é Determinado Durante a Definição da Função, e Não na Invocação ................................ 81
Fechamentos são Causados via Cadeia de Escopo ........................................................................ 82
Capítulo 8........................................................................................................................................ 83
Função (Propriedade prototype) ...................................................................................................... 83
Visão Geral da Cadeia de Protótipo .............................................................................................. 83
Quais os Cuidados Sobre a Propriedade prototype?..................................................................... 84
Protótipo é Padrão em Todas as Instâncias function() .................................................................. 84
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 4/117
4
A Propriedade Padrão prototype é um Objecto Object() .............................................................. 85
Instâncias Criadas de uma Função Construtora são Ligados a Propriedade prototype do Construtor
.................................................................................................................................................... 86
A Última Parada na Cadeia de Protótipo é Object.prototype ........................................................ 87
A Cadeia de Protótipo Retorna a Primeira Propriedade Encontrada na Cadeia ............................. 87
Substituir a Propriedade prototype com um Novo Objeto Remove a Propriedade Padrão do
Construtor ................................................................................................................................... 88
Instâncias que Herdam Propriedades do Protótipo Irão Sempre Pegar os Últimos Valores ........... 89
Substituindo a Propriedade prototype com um Novo Objeto não Atualiza as Instâncias Antigas .. 90
Construtores Definidos pelo Usuários Podem Alavancar a Mesma Herança de Protótipo como
Construtores Nativos ................................................................................................................... 91
Criando Cadeias de Herança (A Intenção Original) ....................................................................... 92
Caítulo 9.......................................................................................................................................... 93
Array()............................................................................................................................................. 93
Visão Geral do Uso de Objetos Array() ......................................................................................... 93
Parâmetros Array() ...................................................................................................................... 94
Propriedade e Métodos Array() ................................................................................................... 95
Instâncias de Objeto Array (Propriedades e Métodos) ................................................................. 95
Criando Vetores ........................................................................................................................... 96
Adicionando e Atualizando Valores em Vetores ........................................................................... 96
Length contra Index ..................................................................................................................... 97
Definindo Vetores com Tamanho Predefinido.............................................................................. 97
Configurando o Tamanho de um Vetor Pode Adicionar ou Remover Valores ............................... 98
Vetores Contendo Outros Vetores (Vetores Multidimensionais) .................................................. 99
Loop Sobre um Vetor, para Frente e para Trás ............................................................................. 99
Capítulo 10.................................................................................................................................... 100
String() .......................................................................................................................................... 100
Visão Geral do Objeto Usando String() ....................................................................................... 100
Parâmetros String ...................................................................................................................... 101
Propriedades e Métodos String() ............................................................................................... 101
Instância de Objeto String (Propriedades e Métodos) ................................................................ 101
Capítulo 11.................................................................................................................................... 103
Number()....................................................................................................................................... 103
Visão Geral do Uso do Objeto Number() .................................................................................... 103Números Inteiros e de Ponto Flutuante ..................................................................................... 103
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 5/117
5
Parâmetros Number() ................................................................................................................ 104
Propriedades Number() ............................................................................................................. 104
Instância de Objeto Number (Propriedades e Métodos) ............................................................ 105
Capítulo 12.................................................................................................................................... 105
Boolean......................................................................................................................................... 105
Visão Geral do Uso de Objeto Boolean() .................................................................................... 105
Parâmetros Boolean() ................................................................................................................ 106
Boolean (Propriedades e Métodos)............................................................................................ 106
Instância de Objeto Boolean (Propriedades e Métodos) ............................................................ 106
Objetos Booleanos Falsos Não Primitivos Convertem Para true ................................................. 107
Algumas Coisas são false (falsas), Todo o Resto é true (verdadeiro) ........................................... 107
Capítulo 13.................................................................................................................................... 108
Trabalhando com Valores Primitivos String, Number, e Boolean .................................................... 108
Valores Literais/Primitivos são Convertidos para Objetos Quando Propriedades são Acessadas . 108
Você Pode Tipicamente Usar Valores Primitivos (String, Number e Boolean) ............................. 110
Capítulo 14.................................................................................................................................... 111
Null ............................................................................................................................................... 111
Visão Conceitual do Uso do Valor null ........................................................................................ 111
typeof Retorna Valores null Como "Objeto" ............................................................................... 112
Capítulo 15.................................................................................................................................... 112
Undefined ...................................................................................................................................... 112
Visão Conceitual do Valor undefined ......................................................................................... 112
JavaScript ECMAScript 3 (e Superior) Declara a Variável undefined no Escopo Global ................ 113
Capítulo 16.................................................................................................................................... 113
Função Math ................................................................................................................................. 113
Visão Conceitual do Objeto Interno Math .................................................................................. 113Propriedades (Math.PI).............................................................................................................. 114
Métodos (Math.random();):....................................................................................................... 114
Math Não é Uma Função Construtora........................................................................................ 115
Math Possui Constantes que Você Não Pode Aumentar/Mutar ................................................. 115
Resumo.................................................................................................................................. 115
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 6/117
6
Capítulo 1
Objetos JavaScript
Criando Objetos Em JavaScript, os objetos são reis. Praticamente tudo é um objeto ou funciona como um objeto.
Entenda os objetos e você irá entender JavaScript. Então vamos examinar a criação de objetos em
JavaScript.
Um objeto é somente um container para uma coleção de valores nomeados (propriedades). Antes
vamos olhar para vários códigos JavaScript. Usando linguagem plana, nós podemos expressar emuma tabela o sujeito "cody":
Cody
Vivo: true
Idade: 33
Sexo: masculino
A palavra "cody" na tabela acima é somente um título para um grupo de propriedades e valores
correspondentes que definem exatamente o que cody é. Como você pode ver na tabela, Eu estou
vivo, tenho 33 anos, e sou homem.
JavaScript, entretanto, não "fala" em tabelas. Ele fala em objetos, que não são como as partes
contidas na tabela "cody". Traduzindo a tabela acima em JavaScript teremos algo parecido com isso:
<!DOCTYPE html> <html Lang="pt-br"> <body> <script>
// cria o objeto cody…
var cody = new Object();
// completa o objeto cody com propriedades (usando a notação do ponto ".")
cody.vivo = true;
cody.idade = 33;
cody.sexo = 'masculino';
console.log(cody); // cria o log do objeto {objeto do tipo Object}
</script> </body></html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 7/117
7
Mantenha isso bem nítido em sua mente: objetos são realmente somente containers para
propriedades, cada uma delas tem um nome e um valor. Esta noção de um container de
propriedades com valores nomeados (um objeto) é usado pelo JavaScript como a construção de
blocos para expressar valores em JavaScript. O objeto cody é um valor que eu expressei como um
objeto JavaScript pela criação de um objeto, dando um nome ao objeto, e depois dando ao objeto
propriedades.
Até agora, o objeto cody que nós estamos discutindo tem somente informação estática. Desde que
nós estamos lidando com linguagem de programação, nós queremos programar nosso objeto cody
para fazer algo. Entretanto, tudo que nós realmente temos é um banco de dados. Para dar vida ao
objeto cody precisamos adicionar um método característico para executar uma função. Para ser
preciso em JavaScript, métodos são propriedades que contém um objeto Function(), que é
necessário para operar uma função ao qual o objeto se destina.
Se quisermos atualizar a tabela cody com um método getSexo, em linguagem plana seria assim:
Cody
Propriedade: Valor da propriedade:
vivo verdadeiro
idade 33
sexo masculino
getSexo retorna o valor da idade
Usando JavaScript, o método getSexo da tabela cody atualizada seria algo parecido com isso:
<!DOCTYPE html> <html lang="pt-br"> <body> <script>
var cody = new Object();
cody.vivo = true;
cody.idade = 33;
cody.sexo = 'masculino';
cody.getSexo = function(){return cody.sexo;};
console.log(cody.getSexo()); //log 'masculino'
</script> </body> </html>
O método getSexo, do objeto cody, é usado para retornar o valor de uma propriedade do objeto
cody: o valor "masculino" armazenado na propriedade sexo. O que você tem que entender é que
sem métodos, nosso objeto não faz nada além de armazenar propriedades estáticas.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 8/117
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 9/117
9
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// define a função construtora Pessoa() para criação de objetos mais tarde
var Pessoa = function (vivo, idade, sexo) {
this.vivo = vivo;
this.idade = idade;
this.sexo = sexo;
this.getSexo = function() {return this.sexo;};
};
// instanciando um objeto Pessoa e armazenando na variável cody
var cody = new Pessoa (true, 33, 'masculino');
console.log(cody);
/* a função construtora String () a seguir, tendo sido definida pelo JavaScript, tem a mesma amostra.
Porque o construtor de string é nativo ao JavaScript, tudo que nós temos que fazer para pegar a
instancia da string é instancia-la. Mas a amostra é a mesma, independente de nós usarmos um
construtor nativo como String() ou usar um construtor definido pelo usuário como em Pessoa() */
// instanciando o objeto String armazenado na variável minhaString
var minhaString = new String ('foo');
console.log(minhaString);
</script> </body> </html>
A função construtora Pessoa () definida pelo usuário pode produzir objetos "pessoas", assim como a
função construtora nativa String() pode produzir objetos strings. A função construtora Pessoa() não é
menos capaz, e não é menos maleável do que a a função construtora String () ou qualquer função
construtora nativa no JavaScript.
Lembre-se de como o objeto cody que vimos primeiro foi produzido a partir de Object(). Isto é
importante de se notar, a função construtora Object() e a nova função construtora Pessoa()
mostradas no código de exemplo anterior podem nos dar saídas idênticas. Ambas podem produzir
um objeto idêntico com as mesmas propriedades e métodos. Examine as duas seções de código a
seguir, mostrando que codyA e codyB possuem os mesmos valores de objeto, mas são criados de
formas distintas.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 10/117
10
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// cria um objeto codyA usando o construtor Object()
var codyA = new Object();
codyA.vivo = true;
codyA.idade = 33;
codyA.sexo = 'masculino';
codyA.getSexo = function() {return codyA.sexo;};
console.log(codyA);
/* o mesmo objeto cody é criado a seguir, mas ao invés de usarmos o construtor nativo Object(),
iremos criar nosso construtor Pessoa() que irá criar o objeto cody (e qualquer outro objeto Pessoa
que quisermos) e depois instancialo com "new". */
var Pessoa = function (vivo, idade, sexo) {
this.vivo = vivo;
this.idade = idade;
this.sexo = sexo;
this.getSexo = function() {return this.sexo;};
};
// instanciando um objeto Pessoa e armazenando na variável codyB
var codyB = new Pessoa (true, 33, 'masculino');
console.log(codyB);
</script></body></html>
A diferença principal entre os objetos codyA e codyB não é o objeto propriamente dito, mas as
funções construtoras usadas para produzir os objetos. O objeto codyA foi produzido usando o
construtor Object(). O construtor Pessoa() construiu codyB, mas também pode ser usando como um
poderoso criador de mais objetos Pessoa().
Ambas as soluções resultaram na criação de um mesmo objeto complexo. Estes são os dois
caminhos mais comuns para a criação de objetos.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 11/117
11
JavaScript é realmente uma linguagem que é pré-empacotada com somente alguns construtores de
objetos nativos usados para construir objetos complexos que expressam tipos específicos de valores
(números, strings, funções, objetos, vetores, etc.), assim como a criação de objetos brutos via
Função() podem criar construtores definidos pelo usuário [Pessoa()]. O resultado final – não
importando o caminho para a criação do objeto – é tipicamente a criação de um objeto complexo.
Entender a criação, natureza, e uso de objetos e seus equivalentes primitivos é o foco do restante
deste livro.
Construtores JavaScript, Construção e Retorno de Instancias de Objetos A regra de uma função construtora é criar múltiplos objetos que compartilham certas qualidades e
comportamentos. Basicamente uma função construtora é um atalho para a produção de objetos que
tem propriedades padrões e métodos proprietários.
Se você disser, "Um construtor não é nada mais do que uma função," então eu responderei, "Você
está correto – a menos que a função seja invocada usando a palavra chave new." [new String('foo')].Quando isso acontece, uma função toma uma regra especial, e o JavaScript trata esta função como
especial, configurando o valor this para a função para os novos objetos sendo criados.
Adicionalmente a este comportamento especial, a função irá retornar o novo objeto criado (this) por
padrão ao invés de um valor falso. O novo objeto que é retornado de uma função é considerado
uma instância da função construtora que o constrói.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 12/117
12
Considere o construtor Pessoa() novamente, mas desta vez leia os comentários a seguir com
cuidado, atente ao efeito da palavra chave new.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
/* Pessoa é uma função construtora. foi escrita com a intenção de ser usada com a palavra chavenew */
var Pessoa = function Pessoa (vivo, idade, sexo) {
/* o "this" a seguir é o novo objeto que está sendo criado (this = new Object();) */
this.vivo = vivo;
this.idade = idade;
this.sexo = sexo;
this.getSexo = function() {return this.sexo;};
/* quando a função é chamada com a palavra chave new, "this" é retornado ao invés de indefinido
*/
};
// instanciando um objeto Pessoa chamado cody
var cody = new Pessoa(true, 33, 'masculino')
// cody é um objeto e uma instancia de Pessoa()
console.log(typeof cody);
console.log(cody);
console.log(cody.constructor);
</script> </body></html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 13/117
13
O código a seguir alavanca uma função construtora definida pelo usuário [Pessoa()] para criar o
objeto cody. Isto não é diferente de um construtor Array() criando um objeto vetor [new Array()]:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// instancia um objeto vetor chamado meuVetor
var meuVetor = new Array(); //meuVetor é uma instancia de Array
// meuVetor é um objeto e uma instancia do construtor Array()
console.log(typeof meuVetor);
console.log(meuVetor);
console.log(meuVetor.constructor);
</script> </body> </html>
Em JavaScript, a maioria dos valores (excluindo valores primitivos) envolvem objetos sendo criados,
ou instanciados, de uma função construtora. Um objeto retornado de um construtor é chamado de
instância. Tenha certeza que você está confortável com essas semânticas, assim como as amostras
de uso de construtores construindo objetos.
Construtores de objetos nativos do JavaScript A linguagem Javascript contêm nove construtores de objetos nativos (ou internos). Estes objetos são
usados pelo JavaScript para construir a linguagem, e por "construir" quero dizer que esses objetos
são usados para expressar valores de objetos no código JavaScript, como uma orquestra de váriascaracterísticas da linguagem. Portanto, os construtores de objetos nativos são multifacetados em
suas produções de objetos, mas são alavancados na facilitação de muitas convenções de muitas
linguagens de programação. Por exemplo, funções são objetos criados de um construtor, mas
também são usados para criar outros objetos quando chamados como funções construtoras usando
a palavra chave new.
A seguir, estão listadas as nove funções construtoras que vem pré-empacotadas com JavaScript:
Number()
String()
Boolean()
Object()
Array()
Function()
Date()
RegExp()
Error()
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 14/117
14
JavaScript é praticamente construído somente com estes nove objetos (assim como os valores
primitivos, string, number, e boolean). Entender estes objetos em detalhes é a chave para se ter
vantagem do poder único e a flexibilidade da programação em JavaScript.
Notas
O objeto Math é o mais "bizarro" aqui. É um objeto estático, diferente de uma função construtora,
com ele você não pode fazer isso: var x = new Math(). Mas você pode usá-lo como se ele já houvesse
sido instanciado (Math.PI). Realmente, Math é somente um objeto namespace configurado pelo
JavaScript para guardar funções matemáticas.
Os objetos nativos são algumas vezes referidos como "objetos globais" desde que eles são objetos
que foram feitos nativamente no JavaScript e disponibilizados para uso. Não confunda o termo
objeto global com objeto global "cabeça" que é o maior nível de sequencia de escopo, por exemplo,
o objeto window em todos os navegadores web.
Os construtores Number(), String(), e Boolean() não constroem objetos somente, eles também
provêm valores primitivos para uma string, numero e booleano, dependendo de como o construtor
é escalado. Se você tiver chamado estes construtores diretamente, então um objeto complexo é
retornado. Se você simplesmente expressar um número, string, ou booleano em seu código (valores
primitivos como 5, "foo" e true), então o construtor irá retornar um valor primitivo ao invés de um
valor de objeto complexo.
Funções Construtoras Não Nativas Definidas Pelo UsuárioComo foi dito com o construtor Pessoa(), nós podemos fazer nossas próprias funções construtoras,
com isso nós podemos produzir não somente um mas múltiplos objetos customizados.
A seguir, está presente a função construtora já familiarizada Pessoa():
<!DOCTYPE html> <html lang="pt-br"> <body> <script>
var Pessoa = function (vivo, idade, sexo) {
this.vivo = vivo;
this.idade = idade;
this.sexo = sexo;
this.getSexo = function() {return this.sexo;};
};
var cody = new Pessoa (true, 33, 'masculino');
console.log(cody);
var lisa = new Pessoa (true), 34, 'feminino');
console.log(lisa);
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 15/117
15
Como você pode ver, passando parâmetros únicos e invocando a função construtora Pessoa(), você
pode facilmente criar um vasto número de objetos de pessoas únicos. Isto pode ser muito útil
quando você precisa de mais de dois ou três objetos que possuem as mesmas propriedades, mas
com valores diferentes. Venha pensar sobre isso, isto é exatamente o que o JavaScript faz com
objetos nativos. O construtor Pessoa() segue os mesmos princípios que o construtor Array(). Então
new Array('foo', 'bar') não é diferente de new Pessoa(true, 33, 'masculino'). Criar suas próprias
funções construtoras é usar a mesma amostra que o JavaScript usa em suas próprias funções
construtoras nativas.
Notas
Isto não é necessário, mas quando criamos funções construtoras customizadas para serem usadas
com o operador new, a melhor prática é fazer o primeiro caractere de uma função construtora em
letra maiúscula: Pessoa() é melhor que pessoa().
Um macete é pensar sobre funções construtoras e o uso do valor this dentro da função. Lembre-se,uma função construtora é somente um atalho. Quando usada com a palavra chave new, isto cria um
objeto com propriedades e valores definidos dentro da função construtora. Quando new é usado, o
valor this literalmente significa que o novo objeto/instancia que será criado baseado em declarações
dentro da função construtora. Na outra mão, se você criar uma função construtora e a chamar sem o
uso da palavra chave new o valor this irá se referir ao objeto "parente" que contêm a função. Mais
detalhes sobre este tópico pode ser encontrado no capítulo 6.
É possível abster-se do uso da palavra chave new e do conceito de função construtora explicitando a
função return em um objeto. A função terá de ser escrita explicitamente para construir um objeto
Object() e retorna-lo: var minhaFuncao = function() {return {prop: val}};. Fazendo isso, entretanto,fazendo com que herde o protótipo.
Instanciando Construtores Usando o Operador newUma função construtora é basicamente um atalho ou modelo usado para criar objetos pré-
configurados. Pegue String() por exemplo. Esta função, quando usada com o operador new [new
String('foo')] cria uma instancia de string baseado no "modelo" String(). Vamos ver um exemplo:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var minhaString = new String('foo');
console.log(minhaString);
</script> </body> </html>
Nós criamos um novo objeto string que é uma instancia da função construtora String(). Com isso, nós
temos um valor de string expresso em JavaScript.
Nota
Eu não estou sugerindo que você use uma função construtora ao invés de seus valores equivalentes
literais/primitivos.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 16/117
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 17/117
17
Nota
Mantenha em mente que Math é um objeto estático – um container para outros métodos – e não é
um construtor que usa o operador new.
Criando Atalhos/Valores Literais a partir de ConstrutoresJavaScript prove atalhos – chamados "literais" – para construir a maioria dos valores de objetos
nativos sem ter que usar new Foo() ou new Bar(). Para a maior parte, a sintaxe literal acompanha o
mesmo sentido como se usasse o operador new. As exceções são: Number(), String(), e Boolean() –
veja notas a seguir.
Se você vem de outros cenários de linguagem de programação, você está familiarizado com o
caminho literal de criação de objetos. A seguir, eu instanciei os construtores JavaScript nativos
usando o operador new e em seguida criei os correspondentes literais equivalentes.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuNumero = new Number(23);
var meuNumeroLiteral = 23;
var minhaString = new String('masculino');
var minhaStringLiteral = 'masculino';
var meuBooleano = new Boolean(false);
var meuBooleanoLiteral = false;
var meuObjeto = new Object();
var meuObjetoLiteral = {};
var meuVetor = new Array('foo','bar');
var meuVetorLiteral = ['foo','bar'];
var minhaFuncao = new Function("x","y", "return x*y");
var minhaFuncaoLiteral = function(x, y) {return x*y};
var meuRegExp = new RegExp('\bt[a-z]+\b');
var meuRegExpLiteral = /\bt[a-z]+\b/;
console.log(meuNumero.constructor, meuNumeroLiteral.constructor);
console.log(minhaString.constructor, minhaStringLiteral.constructor) ;
console.log(meuBooleano.constructor, meuBooleanoLiteral.constructor);
console.log(meuObjeto.constructor, meuObjetoLiteral.constructor);
console.log(meuVetor.constructor, meuVetorLiteral.constructor);
console.log(minhaFuncao.constructor, minhaFuncaoLiteral.constructor);
console.log(meuRegExp.constructor, meuRegExpLiteral.constructor);
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 18/117
18
O que você precisa tomar cuidado aqui é o fato que, em geral, usar literais simplesmente esconde o
processo básico idêntico a usar o operador new. Talvez mais importante, é muito mais conveniente!
Tudo bem, as coisas são um pouco mais complicadas com respeito à string primitiva, e valores
booleanos. Nestes casos, valores literais pegam as características de valores primitivos antes do que
os valores de objetos complexos. Veja a nota a seguir.
Nota
Quando se usa valores literais para string, números, e booleanos, um objeto complexo nunca é
criado antes de o valor ser tratado como um objeto. Em outras palavras, você está lidando com um
tipo de dado primitivo até que você tente usar métodos ou receber propriedades associadas com o
construtor (var caracteresEmFoo = 'foo'.lenght). Quando isso ocorre, JavaScript cria um objeto para
o valor literal por trás das cenas, habilitando o valor a ser tratado como um objeto. Então, depois
que o método é chamado, o JavaScript descarta o objeto e o valor retorna para um tipo literal. Isto é
o porquê de string, números, e booleanos são considerados primitivas (ou simples) estruturas dedados. Espero que isto se torne claro na concepção errônea de que "tudo em JavaScript é um
objeto" e chegue ao conceito certo de que "tudo em JavaScript pode agir como um objeto".
Valores Primitivos (Simples)Os valores 5, 'foo', e false, assim como null e undefined, são considerados primitivos porque eles são
irredutíveis. Isto é, um número é um número, uma string é uma string, um boolean é sempre true ou
false (verdadeiro ou falso), e null e undefined são apenas isto (nulo e indefinido). Estes valores são
inerentemente simples, e não representam valores que possam ser feitos de outros valores.
Examine o código a seguir e pergunte a si mesmo se os valores da string, do número, do booleano,
null (vazio), e undefined (indefinido) podem ser mais complexos. Contraste isso com o que você sabe
de uma instância Object() e uma instância Array() ou qualquer objeto complexo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 19/117
19
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var minhaString = 'string';
var meuNumero = 10;
var meuBooleano = false;
var meuNulo = null;
var meuIndefinido = undefined;
console.log(minhaString, meuNumero, meuBooleano, meuNulo, meuIndefinido);
/* considere que um objeto complexo como um vetor [Array()] ou objeto [Object()] pode ser feito de
múltiplos valores primitivos, e depois tornam-se um conjunto de múltiplos valores complexos */
var meuObjeto = {
minhaString: 'string',
meuNumero: 10,
meuBooleano: false,
meuNulo: null,
meuIndefinido: undefined
};
console.log(meuObjeto);
var meuVetor = ['string', false, null, undefined];
console.log(meuVetor);
</script> </body> </html>
Absolutamente simples, valores primitivos representam a forma diminuída (simplificada) de
dados/informação disponível em JavaScript.
Notas
Ao contrário da criação de valores com sintaxe literal, quando um valor String(), Number(), ou
Boolean() é criado usando a palavra chave new, o objeto criado é atualmente um objeto complexo.
É crítico que você entenda o fato que os construtores String(), Number(), ou Boolean() são
construtores de dupla finalidade usados para criar valores literais/primitivos bem como valores
complexos.
Estes construtores nem sempre retornam objetos, mas, entretanto, quando usado sem o operadornew, podem retornar uma representação primitiva de um valor atual de um objeto complexo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 20/117
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 21/117
21
var meuErro = new Error ('Problema!');
console.log(
typeof meuNumero,
typeof minhaString,
typeof meuBooleano,
typeof meuObjeto,
typeof meuVetor,
typeof minhaFuncao,
typeof minhaData,
typeof meuRegExp,
typeof meuErro
);
</script> </body> </html>
Desejo que você entenda sobre o código de exemplo anterior é que valores primitivos não são
objetos. Valores primitivos são especialmente feitos para representar valores simples.
Como Valores Primitivos São Armazenados/Copiados no JavaScript É extremamente importante saber que valores primitivos são armazenados e manipulados no "valor
de face". Pode soar simples, mas isso significa que se eu armazenar o valor "foo" da string em uma
variável chamada minhaString, então o valor "foo" é literalmente armazenado na memória como é.
Por que isto é importante? Quando você começa a manipular valores (por exemplo: copiando), você
tem que estar equipado com este conhecimento, porque valores primitivos são copiados
literalmente.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 22/117
22
No exemplo a seguir, armazenamos uma cópia do valor de minhaString ('foo') na variável
copiaMinhaString, e esse valor é literalmente copiado. Mesmo se nós mudarmos o valor original, o
valor copiado, referenciado pela variável copiaMinhaString continua o mesmo.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var minhaString = 'foo' // cria o objeto de string primitive
var copiaMinhaString = minhaString // copia o valor de minhaString
var minhaString = null; // manipula o valor armazenado na variável minhaString
/* o valor original de minhaString foi copiado para copiaMinhaString. Isto é confirmado pela
atualização do valor de minhaString e depois checando o valor de copiaMinhaString */
console.log(minhaString, copiaMinhaString);
</script> </body> </html>
O cuidado aqui é que valores primitivos são armazenados e manipulados como valores irredutíveis.
Referenciando a suas transferências seu valor. No exemplo anterior, nós copiamos, ou clonamos, o
valor de minhaString para copiaMinhaString. Quando atualizamos o valor de minhaString, o valor de
copiaMinhaString continua sendo uma cópia do antigo valor de minhaString. Lembre-se disso e
contraste a mecânica aqui com objetos complexos (discutido a seguir).
Valores Primitivos São Igualados Pelo ValorPrimitivos podem ser comparados para ver se seus valores são literalmente os mesmos. Como a
lógica pode sugerir, se você compara uma variável contendo o valor numérico 10 com outra variávelcontendo o valor numérico 10, JavaScript irá considerar esses valores iguais porque 10 é o mesmo
que 10 (10 === 10). O mesmo, é claro, pode ser aplicado se você compara a string primitiva 'foo' a
outra string primitiva com o valor 'foo'. A comparação pode dizer que é igual à outra baseada em seu
valor ('foo' === 'foo').
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 23/117
23
No código a sguir, demonstrarei o conceito da igualdade pelo valor usando números primitivos,
assim como em contraste a isso um objeto complexo numérico.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var preco1 = 10;
var preco2 = 10;
var preco3 = new Number('10'); /* um objeto complexo numérico porque a palavra chave new foi
usada */
var preco4 = preco3;
console.log(preco1 === preco2); // verdadeiro
console.log(preco1 === preco3); /* falso porque preco3 contem um objeto complexo numérico e
preco1 é um valor primitivo */
console.log(preco4 === preco3); /* verdadeiro porque valores complexos são iguais por referência,
não por valor */
preco4 = 10; // O que acontece se atualizarmos preco4 com um valor primitivo?
console.log(preco4 === preco3); //falso, preco4 agora é primitivo ao invés de complexo
</script> </body> </html>
O cuidado aqui é que primitivos, quando comparados, serão checados para ver se os valoresexpressados são iguais. Quando um valor de string, número ou booleano é criado usando a palavra
chave new [new Number('10')], o valor não é mais primitivo. Assim, a comparação não irá funcionar
igual se o valor for criado via sintaxe literal. Isto não é surpreendente, dado que valores primitivos
são armazenados por seu valor (portanto 10 === 10?), enquanto valores complexos são
armazenados por referência (então preco3 e preco4 contêm uma referência para o mesmo valor?).
Os Valores Primitivos String, Number, e Boolean Agem Como Objetos QuandoUsados Como ObjetosQuando um valor primitivo é usado como se fosse um objeto criado por um construtor, JavaScript o
converte para um objeto em ordem para responder para a expressão na mão, mas depois descarta
as qualidades do objeto e o muda para um valor primitivo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 24/117
24
No código a seguir, pego valores primitivos e mostro o que acontece quando valores são tratados
como objetos.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// produção de valores primitivos
var meuNulo = null;
var meuIndefinido = undefined;
var stringPrimitiva1 = "foo";
var stringPrimitiva2 = String('foo'); //não usa new, então é primitiva
var numeroPrimitivo1 = 10;
var numeroPrimitivo2 = Number('10'); //não usa new, então é primitiva
var booleanoPrimitivo1 = true;
var booleanoPrimitivo2 = Boolean('true'); //não usa new, então é primitiva
/* Acessa o método proprietário toString() (herdado por objetos de Object.prototype) para
demonstrar que valores primitivos são convertidos para objetos quando tratados como objetos */
console.log(stringPrimitiva1.toString(), stringPrimitiva2.toString());
console.log(numeroPrimitivo1.toString(), numeroPrimitivo2.toString());
console.log(booleanoPrimitivo1.toString(), booleanoPrimitivo2.toString());
/* isto irá gerar um erro , porque null e undefined não se convertem em objetos e não possuem
construtores */
console.log(meuNulo.toString());
console.log(meuIndefinido.toString());
</script> </body> </html>
No código de exemplo anterior, todos os valores primitivos (exceto null e undefined) são convertidos
para objetos, alavancando o método toString(), e depois retonados para valores primitivos antigos
depois que o método é invocado e retornado.
Valores Complexos (Compostos)Os construtores de objetos nativos Object(), Array(), Function(), Date(), Error(), e RegExp() são
complexos porque podem conter um ou mais valores primitivos ou complexos. Essencialmente,
valores complexos podem ser feitos de diferentes tipos de objetos JavaScript. Pode se dizer que
objetos complexos tem um tamanho desconhecido na memória porque objetos complexos podem
conter qualquer valor e não um valor específico conhecido. No código a seguir, criamos um objeto eum vetor que armazenam todos os objetos primitivos.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 25/117
25
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var objeto = {
minhaString: 'string',
meuNumero: 10,
meuBooleano: false,
meuNulo: null,
meuIndefinido: undefined
};
var vetor = ['string', 10, false, null, undefined];
/* Contraste isso com a simplicidade dos valores primitivos a sguir. Em uma forma primitiva,
nenhum dos valores a seguir pode ser mais complexo do que você vê enquanto valores complexos
podem encapsular quaisquer valores do JavaScript. */
var minhaString = 'string';
var meuNumero = 10;
var meuBooleano = false;
var meuNulo = null;
var meuIndefinido = undefined;
</script> </body> </html>
O cuidado aqui é que valores complexos são uma composição de valores e diferenciam-se em
complexibilidade e composição para valores primitivos.
Nota
O termo "objeto complexo" também é expresso em outras literaturas como "objetos compostos" ou
"tipos de referência". Se não está óbvio, todos estes nomes descrevem a natureza de um valorJavaScript excluindo valores primitivos. Valores primitivos não são "referenciados pelo valor" e não
podem representar uma composição de outros valores. Objetos complexos, na outra mão, são
"referenciados pelo valor" e podem conter ou encapsular outros valores.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 26/117
26
Como Valores Complexos São Armazenados/Copiados no JavaScript É extremamente importante saber que valores complexos são armazenados e manipulados por
referência. Quando se cria uma variável contendo um objeto complexo, você está usando seu nome
(variável ou objeto proprietário) para receber o valor naquele endereço de memória. As implicaçõessão significantes quando você considera o que acontece quando você tenta copiar um valor
complexo. A seguir, nós criamos um objeto armazenado na variável meuObjeto. Depois o valor em
meuObjeto é copiado para a variável copiaDoMeuObjeto. Realmente, isto não é uma cópia do
objeto – está mais para uma cópia do endereço do objeto.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {};
var copiaDoMeuObjeto = meuObjeto; //não é copiado pelo valor, somente a referência é copiada
meuObjeto.foo = 'bar'; //manipula o valor armazenado em meuObjeto
/* Agora se logarmos meuObjeto e copiaDoMeuObjeto, eles irão ter a propriedade foo porque eles
referenciam o mesmo objeto */
console.log(meuObjeto, copiaDoMeuObjeto);
</script> </body> </html>
O que você precisa compreender é isso, ao contrário de valores primitivos que podem copiar um
valor, objetos (valores complexos) são armazenados por referência. Assim como, a referência(endereço) é copiada, mas não o valor atual. Isto significa que objetos não são copiados ao todo.
Como eu disse, o que é copiado é o endereço ou referência ao objeto na fila de memória. No seu
código, por exemplo, meuObjeto e copiaDoMeuObjeto apontam para o mesmo objeto armazenado
na memória.
O grande cuidado aqui é quando você muda um valor complexo – porque ele é armazenado por
referência – você muda o valor armazenado em todas variáveis que referenciam aquele objeto
complexo. No seu código, por exemplo, ambos meuObjeto e copiaDoMeuObjeto são alterados
quando você atualiza o objeto armazenado em cada variável.
Notas
Quando os valores String(), Number(), e Boolean() são criados usando a palavra chave new, ou
convertidos para objetos complexos por trás das cenas, o valor continua a ser armazenado/copiado
pelo valor. Então, mesmo valores primitivos podem ser tratados como valores complexos, eles não
pegam a qualidade de serem copiados por referência.
Para fazer realmente a copia de um objeto, você tem de extrair os valores de um objeto antigo, e
injeta-los em um novo objeto.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 27/117
27
Objetos Complexos São Igualados por ReferênciaQuando comparando objetos complexos, eles são iguais somente quando referenciam o mesmo
objeto (tem o mesmo endereço). Duas variáveis contendo objetos idênticos não são iguais um ao
outro desde que atualmente não apontam o mesmo objeto.
A seguir, objetoFoo e objetoBar tem as mesmas propriedades e são, de fato, objetos idênticos, masquando perguntado se são iguais via ===, JavaScript diz que eles não são.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var objetoFoo = {igual: 'igual'};
var objetoBar = {igual: 'igual'};
//loga falso, JS não os toma como idênticos e do mesmo tipo
//como objetos complexos são medidos pela igualdade
console.log(objetoFoo === objetoBar);
var objetoA = {foo: 'bar'};
var objetoB = objetoA;
console.log(objetoA === objetoB); //loga true (verdadeiro) porque referenciam o mesmo objeto
</script> </body> </html>
O cuidado aqui é que a variável aponta para um objeto complexo na memória que é igual somenteporque estão usando o mesmo "endereço". Contrariamente, dois objetos independentes criados
não são iguais mesmo se eles são do mesmo tipo e possuem exatamente as mesmas propriedades.
Objetos Complexos Possuem Propriedades DinâmicasUma nova variável que aponta para um objeto complexo existente não copia o objeto. Isto é porque
objetos complexos são chamados algumas vezes objetos de referência. Um objeto complexo pode
ter muitas referências como queira, e elas sempre irão se referir ao mesmo objeto, mesmo que o
objeto mude.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var objA = {propriedade: 'valor'};
var apontador1 = objA;
var apontador2 = apontador1;
// atualiza a propriedade objA, e todas as referências (apontador1 e apontador2) são atualizadas
objA.property = null;
// loga 'null null null' porque objA, apontador1 e apontador2 referenciam o mesmo objeto
console.log(objA.property, apontador1.property, apontador2.property);
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 28/117
28
Isto habilita objetos com propriedades dinâmicas porque você pode definir um objeto, criar
referências, atualizar o objeto, e todas as variáveis referenciando para o objeto que "pega" aquela
atualização.
O Operador typeof Usado em Valores Complexos e PrimitivosO operador typeof pode ser usado para retornar o tipo do valor que você está lidando. Mas osvalores retornados por ele não são exatamente consistentes ou o que pode se dizer lógico.
O código a seguir exibe valores retornados de um operador typeof.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// valores primitivos
var meuNulo = null;
var meuIndefinido = undefined;
var stringPrimitiva1 = "string";
var stringPrimitiva2 = String('string');
var numeroPrimitivo1 = 10;
var numeroPrimitivo2 = Number('10');
var primitivoBooleano1 = true;
var primitivoBooleano2 = Boolean('true');
console.log(typeof meuNulo); //loga o objeto? O que? Tenha cuidado...
console.log(typeof meuIndefinido); // loga undefined
console.log(typeof stringPrimitiva1, typeof stringPrimitiva2); //loga string string
console.log(typeof numeroPrimitivo1, typeof numeroPrimitivo2); //loga number number
console.log(typeof primitivoBooleano1, typeof primitivoBooleano2); //loga boolean boolean
//valores complexos
var meuNumero = new Number(23);
var minhaString = new String('masculino');
var meuBooleano = new Boolean(false);
var meuObjeto = new Object();
var meuVetor = new Array('foo', 'bar');
var minhaFuncao = new Function("x","y", "return x * y");
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 29/117
29
var minhaData = new Date();
var meuRegExp = new RegExp('\\bt[a-z]+\\b');
var meuErro = new Error('Problema!');
console.log(typeof meuNumero);
console.log(typeof minhaString);
console.log(typeof meuBooleano);
console.log(typeof meuObjeto);
console.log(typeof meuVetor);
console.log(typeof minhaFuncao);// loga função? O que? Tenha cuidado...
console.log(typeof minhaData);
console.log(typeof meuRegExp); // loga função? O que? Tenha cuidado...
console.log(typeof meuErro);
</script> </body> </html>
Quando usamos operadores em valores, você deve ter cuidado com o potencial dos valores
retornados dados por um tipo de valor (primitivo ou complexo) que você está lidando.
Propriedades Dinâmicas Reservadas para Objetos MutáveisObjetos complexos são feitas de propriedades dinâmicas. Reservados para objetos definidos pelos
usuários – e a maioria dos objetos nativos – a ser mutados. Isto significa que a maioria dos objetos
em JavaScript podem ser atualizados ou modificados a qualquer tempo. Por causa disso, nós
podemos mudar a natureza pré-configurada nativa do JavaScript por si mesma aumentando os
objetos nativos. Entretanto, eu não estou dizendo para você fazer isso; de fato, não penso que você
irá fazer. Mas não vamos manchar o que é possível com opiniões.
Isto quer dizer que é possível armazenar propriedades em construtores nativos e adicionar novos
métodos aos objetos nativos adicionando a eles objetos prototipados.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 30/117
30
No código a seguir, eu mutei a função construtora String() e String.prototype.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
/* aumenta a string interna do construtor Function() com a propriedade propriedadesAumentadas
*/
String.propriedadesAumentadas = [];
if (!String.prototype.trimIT) { // se prototipo não existir, adicione, trimIT()
String.prototype.trimIT = function() {
return this.replace(/^\s+I\s+$/g, '');}// agora adiciona a string trimIT para o vetor propriedadesAumentadasString.propriedadesAumentadas.empurra('trimIT');
}
var minhaString = ' trim ';
console.log(minhaString.trimIT()); /* invoca nosso método para a string customizada trimIT, loga
'trim' */
console.log(String.propriedadesAumentadas.join()); // loga 'trimIT'
</script> </body> </html>
Eu gostaria de dirigir o fato de que objetos em JavaScript são dinâmicos. Isto habilita os objetos em
JavaScript a serem mutados. Essencialmente, toda a linguagem pode ser mutada em uma versão
customizada (método da string trimIT). Novamente, não estou recomendando isso – Estou apenas
apontando que isso é uma parte da natureza dos objetos em JavaScript.
Nota
Cuidado! Se você mutar os trabalhos internos nativos do JavaScript, você terá potencialmente uma
versão customizada do JavaScript para trabalhar. Proceda com cautela, a maioria das pessoas irão
assumir que o JavaScript é sempre o mesmo independente de sua disponibilidade.
Todas as Instâncias Construtoras Possuem Propriedades Construtoras que
Apontam para Suas Funções ConstrutorasQuando um objeto é instanciado, a propriedade construtora é criada atrás das cenas como uma
propriedade do objeto/instância. Estes apontam para a função construtora que criou o objeto. A
seguir, criaremos o objeto Object(), armazenado na variável foo, e depois verificaremos que a
propriedade construtora é disponibilizada para o objeto que criamos.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 31/117
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 32/117
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 33/117
33
Notas
Você pode estar confuso sobre o porquê de valores primitivos terem propriedades construtoras que
apontam para funções construtoras quando objetos não são retornados. Usando um valor primitivo,
o construtor continua sendo chamado, então existe uma relação com valores primitivos e funções
construtoras. Entretanto, o resultado final é um valor primitivo.
Se você quiser que a propriedade construtora log o nome atual de um construtor para expressões de
funções construtoras definidas pelo usuário, você tem que dar o nome atual da expressão da função
construtora (var Pessoa = function Pessoa(){};).
Verificar que um Objeto É uma Instância de uma Função Construtora ParticularUsando o operador instanceof, nós podemos determinar (true ou false) se um objeto é uma
instância particular de uma função construtora.
A seguir, iremos verificar se o objeto InstanciaDoObjetoCustomizado é uma instância da função
construtora ConstrutorCustomizado. Isto funciona tanto com objetos definidos pelo usuário assim
como com objetos nativos criados com o operador new.
<!DOCTYPE html> <html lang ="pt-br"> <body> <script>
//objeto construtor definido pelo usuário
var ConstrutorCustomizado = function() {this.foo = 'bar';};
//instancia do ConstrutorCustomizado
var instanciaDoObjetoCustomizado = new ConstrutorCustomizado();
console.log(instanciaDoObjetoCustomizado instanceof ConstrutorCustomizado); //loga true
//funciona como um objeto nativo
console.log(new Array('foo') instanceof Array) //loga true
</script> </body> </html>
Notas
Uma coisa a se ver por for a quando se lida com o operador instanceof é que irá retornar true todo o
tempo que você perguntar se um objeto é uma instância de Object desde que todos os objetos
sejam herdados do construtor Object().
O operador instanceof irá retornar false quando lidando com valores primitivos alavancados fora do
objeto ('foo' instanceof String //retorna false). Desde que a string 'foo' fosse criada com o operador
new, o operador instanceof retornaria true. Então, tenha em mente que instanceof realmente
funciona somente com objetos complexos e instâncias criadas de funções construtoras que
retornam objetos.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 34/117
34
Uma Instância Criada de um Construtor Pode Ter suas PropriedadesIndependentes (Propriedades de Instância)Em JavaScript, objetos podem ser expandidos a qualquer tempo (propriedades dinâmicas). Como
previamente mencionado, e para ser exato, JavaScript possui objetos mutáveis. Isto significa que
objetos criados de uma função construtora podem ser expandidos com propriedades.
A seguir, eu crio uma instância do construtor Array() e depois expando-a com sua própria
propriedade.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = new Array();
meuVetor.prop = 'teste';
console.log(meuVetor.prop) //loga 'teste'
</script> </body> </html>
Isto pode ser feito com Object(), RegExp(), ou quaisquer outros construtores não primitivos – até
mesmo Boolean().
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
/* isto pode ser feito com qualquer construtor nativo que atualmente produz um objeto */
var minhaString = new String();
var meuNumero = new Number();
var meuBooleano = new Boolean('true');
var meuObjeto = new Object();
var meuVetor = new Array();
var minhaFuncao = new Function('return 2 + 2');
var meuRegExp = new RegExp('\bt[a-z]+\b');
minhaString.prop = 'teste';
meuNumero.prop = 'teste';
meuBooleano.prop = 'teste';
meuObjeto.prop = 'teste';
meuVetor.prop = 'teste';
minhaFuncao.prop = 'teste';
meuRegExp.prop = 'teste';
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 35/117
35
//loga 'teste' 'teste' 'teste' 'teste' 'teste' 'teste' 'teste'
console.log (minhaString.prop, meuNumero.prop, meuBooleano.prop, meuObjeto.prop,
meuVetor.prop, minhaFuncao.prop, meuRegExp.prop);
// tenha cuidado propriedades de instância não funcionam com valores primitivos/literais
var minhaString = 'string';
var meuNumero = 1;
var meuBooleano = true;
minhaString.prop = true;
meuNumero.prop = true;
meuBooleano.prop = true;
// loga undefined undefined undefined (indefinido)
console.log(minhaString.prop, meuNumero.prop, meuBooleano.prop);
</script> </body> </html>
Adicionando propriedades para um objeto criado de uma função construtora não é incomum.
Lembre-se: instancias de objeto criado de uma função construtora são apenas objetos antigos
plenos.
Nota
Mantenha em mente, por trás de suas próprias propriedades, instancias podem ter propriedades
inerentes de um protótipo em cadeia. Ou, como dissemos somente no código, propriedades
adicionadas ao construtor depois do instanciamento. Isto demarca a natureza dinâmica de objetos
no JavaScript.
As Semânticas de "Objetos Javascript" e "Objetos Object()"Não confunda o termo geral "objetos JavaScript", que se referem a noção de objetos em JavaScript
com objetos Object(). Um objeto Object() [var meuObjeto = new Object()] é um tipo muitoespecífico de valor expressado em JavaScript. Assim como um objeto Array() é um tipo de objeto
chamado vetor, um objeto Object() é um tipo de objeto chamado de object. Isto significa que uma
função construtora Object() produz um container genérico para um objeto vazio, que é referido para
um objeto Object(). Similarmente, a função construtora Array() produz objetos vetores, e nos
referimos a esses objetos como objetos Array().
Neste livro, o termo "objeto JavaScript" é usado para se referir a todos os objetos em JavaScript,
porque a maioria dos valores em JavaScript podem agir como um objeto. Isto se dá porque a maioria
dos valores em JavaScript são criados a partir de funções construtoras nativas que produzem um
tipo muito específico de objeto.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 36/117
36
O que você precisa lembrar é que um objeto Object() é um tipo muito específico de valor. É um
objeto genérico vazio. Não confunda isso com o termo "objetos JavaScript" usado para referir-se a
maioria dos valores que podem ser expressos em JavaScript como um objeto.
Capítulo 2
Trabalhando com Objetos e Propriedades
Objetos Complexos Podem Conter a Maioria dos Valores e Propriedades doJavaScript Um objeto complexo pode conter qualquer valor permitido pelo JavaScript. A seguir, eu crio um
objeto Object() chamado meuObjeto e depois adiciono propriedades representando a maioria dos
valores disponíveis em JavaScript.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {};
/* contêm propriedades dentro do meuObjeto representando a maioria dos valores JavaScript
nativos */
meuObjeto.minhaFuncao = function() {};
meuObjeto.meuVetor = [];
meuObjeto.meuNumero = 33;
meuObjeto.minhaData = new Date();
meuObjeto.meuRegExp = /a/;
meuObjeto.meuNulo = null;
meuObjeto.meuIndefinido = undefined;
meuObjeto.meuObjeto = {};
meuObjeto.minhaMatematicaPI = Math.PI;
meuObjeto.meuErro = new Error('Problema!');
console.log (meuObjeto.minhaFuncao, meuObjeto.meuVetor, meuObjeto.meuNumero,
meuObjeto.minhaData, meuObjeto.meuRegExp, meuObjeto.meuNulo, meuObjeto.meuIndefinido,
meuObjeto.meuObjeto, meuObjeto.minhaMatematicaPI, meuObjeto.meuErro);
/* funciona do mesmo modo com objetos complexos, por exemplo uma função (function) */
var minhaFuncao = function() {};
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 37/117
37
minhaFuncao.minhaFuncao = function() {};
minhaFuncao.meuVetor = [];
minhaFuncao.meuNumero = 33;
minhaFuncao.minhaData = new Date();
minhaFuncao.meuRegExp = /a/;
minhaFuncao.meuNulo = null;
minhaFuncao.meuIndefinido = undefined;
minhaFuncao.meuObjeto = {};
minhaFuncao.minhaMatematicaPI = Math.PI;
minhaFuncao.meuErro = new Error('Problema!');
console.log (minhaFuncao.minhaFuncao, minhaFuncao.meuVetor, minhaFuncao.meuNumero,
minhaFuncao.minhaData, minhaFuncao.meuRegExp, minhaFuncao.meuNulo,
minhaFuncao.meuIndefinido, minhaFuncao.meuObjeto, minhaFuncao.minhaMatematicaPI,
minhaFuncao.meuErro);
</script> </body> </html>
O cuidado simples aqui é que objetos complexos podem conter – ou referenciar para – qualquer
coisa que nominalmente expresso em JavaScript. Você pode não estar surpreso quando você vê issopronto, como todos os objetos nativos podem ser mutados. Isto ainda se aplica para valores na
forma de objeto String(), Number() e Boolean() – quando eles são criados com o operador new.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 38/117
38
Encapsulando Objetos Complexos em um Caminho Beneficamente ProgramáticoOs objetos Object(), Array(), e Function() podem conter outros objetos complexos. A seguir
demonstro isso configurando uma árvore de objetos usando Object().
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// encapsulamento usando objetos, cria uma cadeia de objetos
var objeto1 = {
objeto1_1: {
objeto1_1_1: {foo: 'bar'},
objeto1_1_2: {}
},
objeto1_2: {
objeto1_2_1: {},
objeto1_2_2: {}
}
};
console.log(objeto1.objeto1_1.objeto1_1_1.foo); //loga 'bar'
</script> </body> </html>
O cuidado principal aqui é que alguns objetos complexos são projetados para encapsular outros
objetos em um caminho beneficamente programático.
Pegando/Configurando/Atualizando Propriedades de Objetos Usando a Notaçãode Ponto "." ou Chaves "[]"
Nós podemos pegar, configurar, atualizar propriedades de objetos usando ambos (notação de pontoou chaves).
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 39/117
39
A seguir, demonstrarei a notação de ponto, que é acompanhada do uso do nome do objeto seguido
por um período e depois seguido pelas propriedades get, set ou update (pegar, configurar, atualizar
– nomeDoObjeto.propriedade).
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// cria o objeto cody do tipo Object()
var cody = new Object();
// configurando propriedades
cody.vivo = true;
cody.idade = 33;
cody.sexo = 'masculino';
cody.getSexo = function() {return cody.sexo;};
// pegando propriedades
console.log(
cody.vivo,
cody.idade,
cody.sexo,
cody.getSexo()
); //loga 'true 33 masculino masculino'
//atualizando propriedades, exatamente como configurar
cody.vivo = false;
cody.idade = 99;
cody.sexo = 'feminino';
cody.getSexo = function() {return 'Sexo = ' + cody.getSexo;};
console.log(cody);
</script> </body> </html>
A notação de ponto "." é a mais comum para pegar, configurar ou atualizar propriedades de objetos.
A notação de chave "[ ]", a não ser que requerida, não é comumente usada. A seguir, troco a
notação de ponto pela notação de chaves. O nome do objeto é seguido por uma chave de abertura,
o nome da propriedade (entre aspas ' '), e depois a chave de fechamento:
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 40/117
40
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// cria o objeto cody do tipo Object()
var cody = new Object();
// configurando propriedades
cody['vivo'] = true;
cody['idade'] = 33;
cody['sexo'] = 'masculino';
cody['getSexo'] = function() {return cody.sexo;};
// pegando propriedades
console.log(
cody['vivo'],
cody['idade'],
cody['sexo'],
cody['getSexo']()
); //loga 'true 33 masculino masculino'
//atualizando propriedades, exatamente como configurar
cody['vivo'] = false;
cody.['idade'] = 99;
cody['sexo'] = 'feminino';
cody['getSexo'] = function() {return 'Sexo = ' + cody.getSexo;};
console.log(cody);
</script> </body> </html>
A notação de chaves pode ser útil quando você precisa de acesso a uma propriedade chave e o que
você tem de trabalhar com uma variável que contêm valor de string representando o nome
característico. A seguir, demonstrarei a vantagem da notação com chaves sobre a notação de ponto
usando-a para acessar foobar. Faço isso usando duas variáveis que, quando juntas, produzem a
versão de string da propriedade chave contida em objetoFoobar.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 41/117
41
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var objetoFoobar = {foobar: 'Foobar é código sem código'};
var string1 = 'foo';
var string2 = 'bar';
console.log(objetoFoobar[string1 + string2]); //vamos ver a notação de ponto fazer isso!
</script> </body> </html>
Adicionalmente, a notação de chaves pode ser útil para pegar nomes de propriedades características
que são identificadores inválidos no JavaScript. A seguir, uso um número e uma palavra reservada
como nome característico (válida como uma string) que somente a notação de chaves pode acessar.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {'123':'zero','class':'foo'};
/* vamos ver a notação de ponto fazer isso! Mantenha em mente que class é uma palavra reservada
em JavaScript */
console.log(meuObjeto['123'], meuObjeto['class']); //loga 'zero foo'
// não pode fazer o que a notação de chaves pode fazer, de fato causará um erro
//console.log(meuObjeto.0, meuObjeto.class);
</script> </body> </html>
Pelo fato de objetos poderem conter outros objetos, não é incomum ver
cody.objeto.objeto.objeto.objeto ou cody['objeto'] ['objeto'] ['objeto'] ['objeto']. Isto é chamado de
encadeamento de objeto. O encapsulamento de objeto(s) pode crescer indefinidamente.
Objetos são mutáveis em JavaScript. Aceitando que get, set ou update podem ser executados na
maioria dos objetos a qualquer tempo. Usando a notação de chaves (cody['idade']), você pode
arremedar vetores associativos encontrados em outras linguagens.
Se uma propriedade dentro de um objeto é um método, tudo o que você faz é usar os operadores ()[cody.getSexo()] para invocar o método característico.
Deletando Propriedades do ObjetoO operador delete pode ser usado para remover completamente propriedades de um objeto. A
seguir apagamos a característica bar do objeto foo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 42/117
42
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = {bar:'bar'};
delete foo.bar;
console.log('bar' in foo); //loga false, porque bar foi deletado de foo
</scripts> </body> </html>
Notas
Delete não irá apagar propriedades que são encontradas na cadeia de protótipo
Apagar (delete) é o único caminho atualmente para remover uma característica de um objeto.
Configurar a característica para undefined ou null somente altera o valor de uma característica. Isto
não remove a característica do objeto.
Como Referências para Propriedades de Objetos são ResolvidasSe você tentar acessar uma característica que não está contida em um objeto, JavaScript irá sempre
tentar encontrar a característica ou método usando uma sequência característica. A seguir eu crio
um vetor e tento acessar a característica chamada foo que ainda não foi definida.
Você pode pensar que por causa de meuVetor.foo não ser uma propriedade do objeto meuVetor,
JavaScript irá imediatamente retornar undefined. Mas JavaScript irá olhar em mais dois lugares
(Array.prototype e depois Object.prototype) para o valor de foo antes de retornar undefined
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = [];
console.log(meuVetor.foo); //loga undefined
/*JS irá olhar para Array.prototype para Array.prototype.foo, mas não está aqui. Depois irá olhar
para Object.prototype, mão não está lá também. então undefined é retornado*/
</script> </body> </html>
Quando tento acessar a propriedade de um objeto, será checada a instancia do objeto para localizar
essa propriedade. Se ele tiver essa propriedade, será retornado o valor da propriedade, e não há
herança ocorrendo porque a cadeia de protótipo não é alavancada. Se a instância não possui a
propriedade, JavaScript irá então olhar nos objetos da função construtora do objeto prototype.
Toda instância de objeto possui uma propriedade que é um link secreto [_proto_] para a função
construtora que criou a instância. Este link secreto pode ser alavancado para agarrar a função
construtora, especialmente a propriedade prototype de instâncias de funções construtoras.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 43/117
43
Este é um dos aspectos mais confusos no JavaScript. Mas vamos argumentar por fora. Lembre-se
que uma função é também um objeto com propriedades. Faz sentido deixar objetos herdar
propriedades de outros objetos. É como dizer "Ei objeto B, eu gostaria que você compartilhasse
todas as propriedades que o objeto A possui". JavaScript amarra tudo isso para objetos nativos
através do objeto padrão prototype.
Como exatamente JavaScript cumpre isso é confuso até você ver o que é: apenas um conjunto de
regras. Vamos criar um vetor para examinar a propriedade prototype de perto.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//meuVetor é um objeto Array
var meuVetor = ['foo','bar'];
console.log(meuVetor.join()); //join está atualmente definido em Array.prototype.join
</script> </body> </html>
Nossa instância é um objeto com propriedade e métodos. Assim que acessamos um dos métodos,
como join(), vamos nos perguntar: Pode a instância meuVetor criada do construtor Array() ter seu
próprio método join()? Vamos checar.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = ['foo','bar'];
console.log(meuVetor.hasOwnProperty('join')); //loga false
</script> </body> </html>
Não, isso não ocorre. meuVetor ainda tem acesso ao método join() como se ele fosse sua própria
característica. O que aconteceu aqui? Bem, você apenas observou a cadeia de protótipo em ação.
Nós acessamos uma propriedade que, entretanto não está contida no objeto meuVetor, pode ser
encontrada pelo JavaScript em qualquer outro lugar. Este outro lugar é bem específico, quando o
construtor Array() foi criado pelo JavaScript, o método join() foi adicionado (entre outros) como uma
característica da propriedade prototype do Array().
Para reiterar, se você tentar acessar uma propriedade que um objeto não contêm, JavaScript irábuscar por este valor na cadeia prototype. Primeiro vamos olhar para a função construtora que criou
o objeto (Array), e inspecionar seu protótipo (Array.prototype) para ver se a propriedade pode ser
encontrada ali. Se o primeiro protótipo do objeto não tiver a propriedade, então JavaScript continua
procurando na cadeia de construtores por trás do construtor inicial. Isto pode percorrer até o fim da
cadeia.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 44/117
44
Onde a cadeia termina? Vamos examinar o exemplo novamente invocando o método
toLocaleString() em meuVetor:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//meuVetor e Array.prototype não contêm o método toLocaleString()
var meuVetor = ['foo','bar'];
//toLocaleString() está atualmente definido em Object.prototype.toLocaleString
console.log(meuVetor.toLocaleString()); //loga 'foo,bar'
</script> </body> </html>
O método toLocaleString() não está definido com o objeto meuVetor. Então a regra de cadeia de
protótipo é invocada e JavaScript olha para a propriedade prototype no construtor Array
(Array.prototype). Não foi encontrada ainda, então a regra da cadeia é invocada novamente e nós
olhamos para a propriedade prototype no Object() (Object.prototype). E sim, é encontrada aqui. Se
não fosse encontrada, JavaScript iria produzir um erro dizendo que a propriedade era indefinida
(undefined).
Desde que todas as propriedades prototype são objetos, o link final na cadeia é Object.prototype.
Não há outro construtor com a propriedade prototype que possa ser examinado.
Existe um capítulo inteiro a frente que quebra a cadeia prototype em partes menores, então se você
está completamente perdido, leia o Capítulo 8 e depois volte para solidificar sua compreensão.
Desta curta leitura, espero que tenha entendido que quando uma propriedade não é encontrada (ese torna undefined), JavaScript olhou vários protótipos de objetos para determinar que a
propriedade é undefined. A procura sempre ocorre, e esse processo de procura é como o JavaScript
trabalha com herança como uma simples procura de propriedade.
Usando hasOwnProperty, Verificar que uma Propriedade de Objeto Não é da
Cadeia de ProtótipoEnquanto o operado in pode checar propriedades de um objeto, incluindo propriedades de uma
cadeia de protótipo, o método hawOwnProperty pode checar um objeto para uma propriedade que
não é da cadeia de protótipo.
A seguir, queremos saber se meuObjeto contêm a propriedade foo, e que não está herdando a
propriedade da cadeia de protótipo.
A seguir, queremos saber se meuObjeto contêm a propriedade foo, e que não é que não está
herdando a propriedade da cadeia de protótipo. Para fazer isso, perguntamos se meuObjeto possui
sua própria propriedade chamada foo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 45/117
45
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {foo:'value'};
console.log(meuObjeto.hasOwnProperty('foo')) //loga true
//vs. uma propriedade da cadeia de protótipo
console.log(meuObjeto.hasOwnProperty('toString')) //loga false
</script> </body> </html>
O método hasOwnProperty pode ser alavancado quando você precisa determinar se uma
propriedade é local para um objeto ou herdada da cadeia de protótipo.
Checando se um Objeto Contêm uma dada Propriedade Usando o Operador inO Operador in é usado para verificar (true ou false) se um objeto contém uma dada propriedade. A
seguir, estamos checando para ver se foo é uma propriedade em meuObjeto.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {foo:'value'};
console.log('foo' in meuObjeto); //loga true
</script> </body> </html>
Você deve tomar cuidado pois o operador in não checa apenas propriedades contidas no objeto
referenciado, mas também por quaisquer propriedades que o objeto herde via cadeia de protótipo.Então, as mesmas regras de procura de propriedades, se não no objeto atual, serão buscadas na
cadeia de protótipo.
Isto significa que meuObjeto no código a seguir atualmente contêm o método característico toString
via cadeia de protótipo (Object.prototype.toString), mesmo sem termos especificado um
(meuObjeto.toString = 'foo').
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {foo:'value'};
console.log('toString' in meuObjeto); //loga true
</script> </body> </html>
No ultimo código de exemplo, a característica toString não está literalmente dentro de meuObjeto.
Entretanto, é herdado de Object.prototype e então o operador in conclui que meuObjeto de fato
possui um método característico toString() herdado.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 46/117
46
Enumerar Propriedades de Objetos Usando o Loop forUsando for, nós podemos fazer um loop sobre cada propriedade em um objeto. No código a seguir,
estamos usando o loop em for para pegar os nomes das propriedades do objeto cody.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var cody = {
idade: 23,
sexo: 'masculino'
};
for (var key in cody) { //key é uma variável usada para representar cada nome de propriedade
//evita propriedades herdadas da cadeia de protótipo
if(cody.hasOwnProperty(key)){
console.log(key);
}
}
</script> </body> </html>
Notas
O for no loop tem um abatimento. Ele não acessa apenas as propriedades do objeto especifico que
está no loop, mas também incluem no loop quaisquer propriedades herdadas (via cadeia de
protótipo) do objeto. Então, se isso não for o resultado desejado (como na maioria dos casos), temos
que usar uma simples declaração if dentro do loop para ter certeza que iremos acessar somente as
propriedades contidas no objeto específico. Isto pode ser feito usando o método hasOwnProperty(),
herdada por todos os objetos.
A ordem em que as propriedades são acessadas no loop nem sempre é a ordem em que foram
definidas no loop. Adicionalmente a ordem em que as propriedades foram definidas não são
necessariamente a ordem em que são acessadas.
Somente propriedades que são enumeráveis (disponíveis quando o loop esta sobre as propriedades)
são mostradas pelo loop for. Por exemplo, a característica construtora não será mostrada. É possível
checar quais propriedades são enumeráveis com o método propertyIsEnumerable().
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 47/117
47
Objetos Host Contra Objetos Nativos
Você deve ter cuidado com o ambiente de desenvolvimento em que o JavaScript é executado(navegador web), pois os navegadores tipicamente contêm o que é conhecido como objetos host
(host objects). Objetos host não fazem parte da implementação ECMAScript, mas são disponíveis
como objetos durante a execução. É claro a disponibilidade e comportamento dos objetos host
depende completamente sobre o que o desenvolvimento provê.
Por exemplo, no ambiente do navegador web o objeto window/head e todos os objetos que ele
contem (excluindo os providos pelo JavaScript) são considerados objetos host.
A seguir eu examino as propriedades do objeto window.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
for (x in window) {
console.log(x); //loga todas as propriedades do objeto window/head
}
</script> </body> </html>
Você deve ter percebido que os objetos JavaScript nativos não foram listados junto com os objetos
host. É comum os navegadores web distinguirem entre objetos host e objetos nativos.
Como eles pertencem ao navegador web, o mais famoso de todos os objetos host é a interface para
trabalhar com documentos HTML, também conhecido como DOM. A seguir, um método para listar
todos os objetos contidos dentro do objeto window.document provido pelo ambiente do navegador
web.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
for (x in window.document) {
console.log(x);
}
</script> </body> </html>
O que eu desejo que você aprenda aqui é que a especificação JavaScript não afeta por si só os
objetos host e vice versa. Existe uma linha divisora entre o que o JavaScript provê (JavaScript 1.5,
ES3 contra Mozilla´s JavaScript 1.6,1.7,1.8,1.8.1,1.8.5) e o que o ambiente de objetos host provê, e
esses dois não podem ser confundidos.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 48/117
48
Notas
O ambiente host (navegador web) que executa código JavaScript, tipicamente provê o objeto head
(objeto window no navegador web) onde as porções nativas da linguagem são armazenadas
juntamente com os objetos host (window.location no navegador web) e objetos definidos pelo
usuário (o código que você escreve para executar no navegador web).
Não é incomum para os produtores de navegadores web adiantarem-se com os objetos host e
adicionarem futuras especificações para o JavaScript antes que sejam aprovadas (Mozzila´s Firefox,
JavaScript 1.6, 1.7, 1.8, 1.8.1, 1.8.5).
Melhorando e Estendendo Objetos com Underscore.jsJavaScript está fraquejando quando chega a hora de seriamente manipular e gerenciar objetos. Se
você está executando JavaScript em um navegador web, gostaria de grifar e sugerir o uso de
Underscore.js quando você precisa de mais funcionalidades do que as providas pelo JavaScript 1.5.
Underscore.js provê as seguinte funcionalidades quando lidando com objetos.
Estas funções funcionam em todos os objetos e vetores:
each()
map()
reduce()
reduceRught()
detect()
select()
reject()
all()
any()
include()
invoke()
pluck()
max()
min()
sortBy()
sortIndex()
toArray()
size()
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 49/117
49
Estas funções funcionam em todos os objetos:
keys()
values()
functions()
extend()
clone()
tap()
isEqual()
isEmpty()
isArray()
isArguments()
isFunction()
isString()
isNumber
isBoolean
isDate
isRegExp
isNaN
isNull
isUndefined
Eu gosto desta biblioteca porque tem a vantagem das novas adições nativas do JavaScript que os
navegadores web suportam, mas também provê a mesma funcionalidade para navegadores web
que não suportam, tudo sem mudar a implementação nativa do JavaScript a menos que assim
quisermos.
Nota
Antes de você iniciar o uso de Underscore.js tenha certeza de que a funcionalidade que você precisa
não é provida pela biblioteca JavaScript ou framework que talvez possa ser usado em seu código.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 50/117
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 51/117
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 52/117
52
Propriedades Instanciadas e Métodos do Objeto Object()Instâncias de objetos Object() possuem as seguintes propriedades e métodos:
Propriedades Instanciadas (var meuObjeto = {}; meuObjeto.constructor;):
constructor
Métodos Instanciados (var meuObjeto = {}; meuObjeto.toString();):
hasOwnProperty()
isPrototypeOf()
propertyIsEnumerable()
toLocaleString()
toString()
valueOf()
Nota
A cadeia de protótipo termina com Object.prototype e todas as propriedades e métodos de Object()
(mostrados a seguir) são herdados por todos os objetos JavaScript.
Criando Objetos Object() Usando "Objetos Literais"Criar "um objeto literal" instanciando o objeto com ou sem propriedades usando suspensórios (var
cody = {};). Você se lembra do início do capitulo 1, quando criamos o objeto cody e depois demospropriedades ao objeto cody usando a notação de ponto "."? Vamos fazer isso novamente:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var cody = {
vivo:true,
idade:23,
sexo:'masculino',
getSexo: function() {return cody.sexo;}
};
console.log(cody);
</script> </body> </html>
Observe no código a seguir que criar o objeto cody e suas propriedades levam 5 sentenças. Usando a
notação de "objeto literal", podemos expressar o mesmo objeto cody em uma sentença.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 53/117
53
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var cody = {
vivo:true,
idade:23,
sexo:'masculino',
getSexo: function() {return cody.sexo;}
};
console.log(cody)
</script> </body> </html>
Usando a notação literal nos da a habilidade de criar objetos, incluindo propriedades definidas, com
menos código e visualmente encapsula dados relacionados. Observe o uso dos operadores ";" e "."
(sem aspas) em uma sentença. Isto é atualmente a sintaxe preferida para criar objetos em JavaScript
por causa da concisão e legibilidade.
Tenha cuidado pois os nomes de propriedades podem ser especificados como strings:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var cody = {
'vivo':true,
'idade':23,
'sexo':'masculino',
'getSexo': function() {return cody.sexo;}
};
console.log(cody);
</script> </body> </html>
Não é necessário especificar propriedades como strings a menos que o nome:
Seja uma das palavras reservadas (class por exemplo)
Contenha espaços ou caracteres especiais (qualquer coisa alem de números, letras, o símbolo de
dólar "$" ou o caractere underscore "_"
Inicie com um número
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 54/117
54
Nota
Cuidado, a última propriedade de um objeto não pode ter vírgula. Isto causará erro em alguns
ambientes de desenvolvimento JavaScript.
Todos os Objetos são Herdados do Object.prototypeA função construtora Object() no JavaScript é especial, assim como a característica prototype é a
ultima parada da cadeia de protótipo.
A seguir, eu estendo Object.prototype com a propriedade foo, depois crio uma string e tento acessar
a propriedade foo como se fosse uma propriedade da instância. Desde que a instância minhaString
não possui uma propriedade foo, a cadeia de protótipo "chuta" o valor procurado para
String.prototype, que é o local final que o JavaScript irá procurar por um valor de objeto. O valor foo
é encontrado em Object.prototype porque eu o adicionei, então retorna o valor de foo.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
Object.prototype.foo = 'foo';
var minhaString = 'bar';
//loga 'foo' encontrado em Object.prototype.foo via cadeia de protótipo
console.log(minhaString.foo);
</script> </body> </html>
Nota
Cuidado! Qualquer coisa adicionada em Object.prototype será mostrada em um loop for e a cadeia
de protótipo. Por causa disso, é dito que mudar Object.prototype é proibido, assim alguns podem
dizer.
Capítulo 4
Function()
Visão Conceitual Geral do Uso de Objetos Function()Uma função é um container de sentenças de código que podem ser invocados usando os operadores
parênteses (). Sentenças podem ser passadas dentro dos parênteses durante a invocação então as
sentenças na função podem acessar certos valores quando a função é invocada.
A seguir, criamos duas versões de um objeto função adicioneNumeros – um usando o operador new
e outro usando amostra literal comum. Ambos estão esperando duas sentenças. Em cada caso, nós
invocamos a função, passando sentenças nos operadores parênteses ().
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 55/117
55
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var adicioneNumerosA = new Function ('num1', 'num2', 'return num1 + num2');
console.log(adicioneNumerosA(2, 2)); //loga 4
//também pode ser escrito de forma literal, que é mais comum
var adicioneNumerosB = function(num1, num2) {return num1 + num2};
console.log(adicioneNumerosB(2, 2)); //loga 4
</script> </body> </html>
Uma função pode ser usada para retornar um valor, construir um objeto, ou como um mecanismo
para simplesmente executar código. JavaScript possui vários usos para funções, mas na forma mais
básica, uma função é simplesmente um escopo único de sentenças executáveis.
Parâmetros Function()O construtor Function() toma um número indefinido de parâmetros, mas o último parâmetro
aguardado pelo construtor Function() é uma string contendo sentenças que abrangem o corpo da
função. Quaisquer parâmetros passados para o construtor antes do último estará disponível para a
função sendo criada. Também é possível enviar múltiplos parâmetros separados por vírgula.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var adicioneFuncao = new Function('num1', 'num2', 'return num1 + num2');
/* alternativamente uma string simples separada por vírgula com argumentos pode ser o primeiro
parâmetro de um construtor, com a função de corpo seguindo */
var multiplicaFuncao = new Function('num1, num2', 'return num1 * num2');
console.log(adicioneFuncao(2,2), multiplicaFuncao(2,2)); //loga '4 4'
//contra a forma mais comum de instanciar uma função
var adicioneFuncao = function(num1, num2) {return num1 + num2;}; //forma de expressão
function adicioneFuncao(num1, num2) {return num1 + num2;} //forma de sentença
</script> </body> </html>
Notas
Alavancando diretamente o construtor Function() não é recomendado ou tipicamente nunca é feito
porque o JavaScript irá usar eval() para avaliar a string contendo a lógica da função. Muitos
consideram eval() como desnecessário.
Usar o construtor Function() sem a palavra chave new tem o mesmo efeito que usar somente o
construtor para criar objetos function [new Function('x', 'return x') contra function('x', 'return x')].
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 56/117
56
Nenhum fechamento é criado (veja Capítulo 7) quando se invoca o construtor Function()
diretamente.
Propriedades e Métodos Function()O objeto function possui as seguintes propriedades (não incluindo propriedades e métodos
herdados):
Propriedades(Funcao.prototype)
prototype
Instâncias de Propriedades e Métodos do Objeto FunctionAs instâncias do objeto function possuem as seguintes propriedades e métodos:
Instâncias de Propriedades (var minhaFuncao = function(x, y, z) {}; minhaFuncao.length;):
arguments
constructor
length
Instâncias de Métodos (var minhaFuncao = function(x, y, z) {}; minhaFuncao.toString();):
apply()
call()
toString()
Funções Sempre Retornam um ValorEnquanto é possível criar uma função para simplesmente executar sentenças de código, é muito
comum para uma função retornar um valor. A seguir, estamos retornando uma string da função
digaOi.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var digaOi = function() {
return 'Oi';
};
console.log(digaOi()); //loga 'Oi'
</script> </body> </html>
Se uma função não específica um valor de retorno, então undefined é retornado. A seguir,
chamamos a função berro, que loga a string 'berro' no console sem termos especificado um valor de
retorno.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 57/117
57
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var berro = function() {
console.log('Eu estou berrando!');
// funções retornam undefined mesmo não estando indefinidas
}
//loga true porque um valor sempre é retornado mesmo sem termos especificado um retorno
console.log(berro() === undefined);
</script> </body> </html>
O cuidado aqui é que todas as funções retornam um valor, mesmo sem termos provido um valor de
retorno. Se você não especificar um valor de retorno, o valor retornado é undefined.
Funções são os Cidadãos de Primeira Classe (Não Apenas Sintaxe, mas Valores)Em JavaScript, funções são objetos. Isto significa que uma função pode ser armazenada em uma
variável, vetor ou objeto. Também, uma função pode ser passada para, e retornada de, uma função.
Uma função possui propriedades porque é um objeto. Todos estes fatores fazem da função um
cidadão de primeira classe no JavaScript.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// funções podem ser armazenadas em variáveis (funcA), vetores (funcB), e objetos (funcC)
var funcA = function(){}; //chamada como funcA()
var funcB = [function(){}]; //chamada como funcB[0]()
var funcC = {method: function(){}}; //too.method() ou funcC['method']()
// funções podem ser enviadas para, enviadas por, funções
var funcD = function(func){
return func
};
var executaFuncaoPassadaParaFuncaoD = funcD(function(){console.log('Oi');});
executaFuncaoPassadaParaFuncaoD();
// funções são objetos, que significa que tem propriedades
var funcE = function(){};
funcE.answer = 'yup'; //instância da propriedade
console.log(funcE.answer); //loga 'yup'
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 58/117
58
É crucial que você entenda que uma função é um objeto, e também um valor. Pode ser passada em
torno ou aumentada como qualquer outra expressão em JavaScript.
Passando Parâmetros para uma FunçãoParâmetros são veículos para passar valores no escopo de uma função quando é invocada. A seguir,
como nós invocamos adicionaFuncao(), desde que predefinimos para pegar dois parâmetros, doisvalores adicionados se tornam disponíveis no escopo.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var adicionaFuncao = function(numero1, numero2){
var soma = numero1 + numero2;
return soma;
}
console.log(adicionaFuncao(3,3)); //loga 6
</script> </body> </html>
Notas
Em contraste a outras linguagens de programação, é perfeitamente legal em JavaScript omitir
parâmetros mesmo se a função foi definida para aceitar esses argumentos. Os valores perdidos são
dados pelo valor undefined. É claro, deixando valores de fora dos parâmetros, a função pode não
funcionar corretamente.
Se você passar um parâmetro inesperado para uma função (não definida quando a função foi
criada), nenhum erro irá ocorrer. É possível acessar estes parâmetros do objeto arguments, que é
disponibilizado para todas as funções.
Valores Disponíveis para Todas as Funções (this e arguments)Dentro do escopo/corpo de todas as funções, valores this e arguments são disponíveis.
O objeto arguments é um objeto como um vetor (array) contendo todos os parâmtros sendo
passados para a função. No código a seguir, mesmo se esquecendo de especificar os parâmetros
quando definimos a função, nós podemos confiar no vetor arguments passado para a função para
acessar parâmetros se eles enviarem sobre a invocação.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var adiciona = function() {
return arguments[0] + arguments[1];
};
console.log(adiciona(4, 4)); //retorna 8
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 59/117
59
A palavra chave this, passada para todas as funções, é uma referência para o objeto que contêm a
função. Como você pode esperar, funções contidas com objetos como propriedades (métodos)
podem usar this para ganhar uma referência para o objeto "parente". Quando uma função é
definida no escopo global, o valor this é um objeto global. Reveja o código a seguir e tenha certeza
de entender o que this está retornando.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto1 = {
nome: 'meuObjeto1',
meuMetodo: function(){console.log(this);}
};
meuObjeto1.meuMetodo(); //loga 'meuObjeto1'
var meuObjeto2 = function(){console.log(this);};
meuObjeto2(); //loga window
</script> </body> </html>
A Propriedade arguments.calleeO objeto arguments possui uma propriedade chamada callee, que é uma referência para a função
atualmente sendo executada. Esta propriedade pode ser usada para referenciar a função com o
alcance do escopo da função (arguments.callee).
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = function foo() {
console.log(arguments.callee); //loga foo()
//calle pode ser usado para invocar recursivamente a função foo
}();
</script> </body> </html>
Isto pode ser útil quando uma função precisa ser chamada recursivamente.
Instância de Função, Propriedade length e arguments.lengthO objeto arguments possui uma propriedade única (length). Enquanto você pode pensar que esta
propriedade length irá lhe dar o número de argumentos definidos, isto atualmente lhe dá o número
de parâmetros enviados para a função durante a invocação.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 60/117
60
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var minhaFuncao = function(z, s, d) {
return arguments.length;
};
console.log(minhaFuncao()); // loga 0 porque não há parâmetros sendo passados para a função
</script> </body> </html>
Usando a propriedade length de todas as instâncias Function(), nós podemos atualmente pegar o
número total de parâmetros que a função está aguardando.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var minhaFuncao = function(z, s, d, e, r, m, q) {
return minhaFuncao.length;
};
console.log(minhaFuncao()); //loga 7
</script> </body> </html>
Nota
A propriedade arguments.length começou com o JavaScript 1.4 e está descontinuada, e o número deargumentos enviados para uma função podem ser acessados pela propriedade length do objeto
function. Então, movendo para frente, você pode pegar o valor do tamanho alavancando a
propriedade callee para primeiro ganhar referência para a função que está sendo invocada
(arguments.callee.length).
Redefinindo Parâmetros de FunçãoFunções podem ser canceladas a qualquer tempo durante a invocação usando a palavra chave
return com ou sem valor. A seguir, estamos cancelando a função adiciona se os parâmetros forem
undefined ou não for um número.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var adiciona = function(x, y) {
//se os parêmetros não forem números, retorna erro
if (typeof x !== 'number' || typeof y !== 'number') {return 'use números';}return x + y;
}console.log(adiciona(3,3)); //loga 6
console.log(adiciona('2','2')); //loga 'use números'</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 61/117
61
O cuidado aqui é que você pode cancelar a execução de uma função usando a palavra chave returnem qualquer ponto de execução da função.
Definindo uma Função (Sentença, Expressão, ou Construtor)Uma função pode ser definida em três caminhos diferentes: uma função construtora, uma função desentença, ou uma função de expressão. A seguir, demonstro cada variação.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
/* função construtora, o ultimo parâmetro é uma função lógica, qualquer coisa antes é umparâmetro */
var construtorAdiciona = new Function('x', 'y', 'return x + y');
// função sentençafunction sentencaAdiciona(x, y) {
return x + y;}
// função expressãovar expressaoAdiciona = function(x, y) {
return x + y;};console.log(construtorAdiciona(2,2), sentencaAdiciona(2,2), expressaoAdiciona(2,2));
//loga '4 4 4'</script> </body> </html>
Nota
Alguns dizem que há um quarto tipo de definição para funções, chamada "expressão de funçãonomeada". Uma função nomeada é simplesmente uma função expressão que também contém umnome (var adiciona = function adiciona(x, y) {return x + y}).
Invocando uma Função [Função, Método, Construtor, ou call() e apply()]
Funções são invocadas usando diferentes tipos de cenários:
Como uma funçãoComo um métodoComo um construtorUsando apply() ou call()
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 62/117
62
No código a seguir, examinamos cada uma destas invocações:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// função
var minhaFuncao = function() {return 'foo'};console.log(minhaFuncao()); //loga 'foo'
// métodovar meuObjeto = {minhaFuncao: function(){return 'bar';}}console.log(meuObjeto.minhaFuncao()); //loga 'bar'
// construtorvar Cody = function(){
this.vivo = true;this.idade = 33;
this.sexo = 'masculino';this.getSexo = function() {return this.sexo;};}var cody = new Cody(); // invoca via construtor Codyconsole.log(cody); // loga o objeto e propriedades de cody
//apply() e call()var cumprimento = {
executaCumprimento: function(){console.log(this.nome, arguments[0], arguments[1]);
}
}var cody = {nome: 'cody'};var lisa = {nome: 'lisa'};
// invoca a função executaCumprimento como se ela estivesse dentro do objeto codycumprimento.executaCumprimento.call(cody, 'foo', 'bar'); //loga 'cody foo bar'
// invoca a função executaCumprimento como se ela estivessa dentro do objeto lisacumprimento.executaCumprimento.apply(lisa, ['foo', 'bar']); //loga 'lisa foo bar'
/* observe a diferença entre call() e apply() e como os parâmetros são enviados para a função que
está sendo invocada */</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 63/117
63
Funções Anônimas
Uma função anônima é uma função que não recebe identificador. Funções anônimas são maiscomumente usadas para passar funções como parâmetros para outra função.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>// function(){console.log('oi');}; //função anônima, mas sem caminho para invocar
//cria uma função que invoca nossa função anônimavar digaOi = function(f){
f(); //invoca a função anônima}
//passa uma função anônima como parâmetrodigaOi(function(){console.log('Oi');}); //loga 'Oi'
</script> </body> </html>
Função Expressão Auto-Invocada
Uma função expressão (realmente qualquer função exceto uma criada pelo construtor Function())pode ser imediatamente invocada depois da definição usando os operadores parênteses. A seguir,criamos a função expressão digaPalavra() e depois imediatamente invocamos a função. Isto éconsiderado como uma função expressão auto-invocada.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var digaPalavra = function() {console.log('Palavra');}();//loga 'Palavra'</script> </body> </html>
Função Sentença Anônima Auto-Invocada
É possível criar uma função sentença anônima que é auto-invocada. Isto é chamado de uma funçãosentença anônima auto-invocada. A seguir, nós criamos várias funções anônimas que sãoimediatamente invocadas.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>//forma mais comum(function(msg) {
console.log(msg);})('Oi');
//um pouco diferente mas faz a mesma coisa(function(msg) {
console.log(msg)}('Oi'));
//a solução mais curta possível!function digaOi(msg) {console.log(msg);}('Oi');
//isto não funciona
//function digaOi() {console.log('Oi');}();</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 64/117
64
Funções Podem Ser Aninhadas
Funções podem ser aninhadas dentro de outras funções indefinidamente. A seguir, nósencapsulamos a função bom dentro da função bar, que estão dentro da função foo.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>var foo = function() {
var bar = function() {var bom = function(){
console.log(this); //loga a referência para o objeto cabeça window}();
}();}();</script> </body> </html>
O cuidado simples aqui é que funções podem ser aninhadas e que não existe limite de profundidade
para o processo de aninhar.
Nota
Lembre-se, o valor de this para funções aninhadas será o objeto cabeça (objeto window em umnavegador web) no JavaScript 1.5, ECMAScript 3ª Edição.
Passando Funções para Funções e Retornando Funções de Funções
Como previamente mencionado, funções são os cidadãos de primeira classe em JavaScript. E desde
uma função é um valor, e uma função pode ser passada com qualquer tipo de valor, uma funçãopode ser passada para uma função. Funções que pegam e/ou retornam outras funções são algumasvezes chamadas de "funções de alta ordem".
A seguir, estamos passando uma função anônima para a função foo, que nós então imediatamenteretornamos da função foo. É uma função anônima que a variável bar aponta, desde foo que aceita edepois retorna a função anônima.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//funções podem ser enviadas para, e enviadas de volta de, funções
var foo = function(f) {return f;
}
var bar = foo(function() {console.log('Oi');});
bar(); //loga 'Oi'
</script> </body> </html>
Então bar é invocada, e invoca a função anônima que é passada para a função foo(), que é então
retorna da função foo() e referenciada pela variável bar. Tudo isso é para mostrar o fato de quefunções podem passar em torno como qualquer outro valor.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 65/117
65
Invocando Função Sentença Antes de Ser Definida (Levantamento de Função)
Uma função sentença pode ser invocada durante a execução antes de sua definição atual. Isto é um
pouco bizarro, mas você deve tomar cuidado com isso, para então alavancar, ou ao menos saber oque está acontecendo quando se deparar com algo assim. A seguir, invoco as funções sentençadigaOi() e soma() antes de serem definidas.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//exemplo 1
var falar = function() {digaOi(); /* digaOi() não foi definida ainda, mas ainda continua podendo ser invocada */function digaOi() {console.log('Oi');}
}(); //invoca
//exemplo 2
console.log(soma(2,2)); /* invoca soma(), que não foi definida ainda, mas ainda continua podendoser invocada */
function soma(x, y) {return x + y;}
</script> </body> </html>
Isto acontece porque antes do código ser executado, funções sentença são interpretadas eadicionadas a pilha/contexto de execução. Tenha certeza que você está confortável com o uso defunções sentença.
Nota
Funções, definidas como "funções expressão" não são levantadas – somente "funções sentença" sãolevantadas.
Uma Função Pode Chamar a Si Mesma (Recursividade)
É perfeitamente legitimo para uma função chamar a si mesma. De fato isto é amiúde usado emamostras bem conhecidas de programação. No código a seguir, nós "chutamos para fora" a funçãocontagem. Essencialmente, isso cria um loop que conta de 5 a 0.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>var contagem = function contagem(num) {
console.log(num);num--; //muda o parâmetro do valorif (num < 0) {return false;} //se num < 0 retorna a função sem recursividade/* também pode ser feito com arguments.callee(num) se estivesse em uma função anônima */contagem(num);
};
contagem(5); //chuta para fora a função, que loga separadamente 5, 4, 3, 2, 1, 0
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 66/117
66
Você deve tomar cuidado, pois não é incomum uma função chamar a si mesma (recursividade) oufazer algo repetitivamente.
Capítulo 5
O Objeto Cabeça/Global
Visão Geral do Conceito do Objeto Cabeça
O código JavaScript, por si, pode ser contido como um objeto. Como exemplo, quando"desenhamos" código JavaScript para um ambiente de navegador web, JavaScript é contido e
executado com o objeto window. Este objeto window é considerado como "objeto cabeça", oualgumas vezes confusamente referido como "o objeto global". Todas as emplementações doJavaScript requerem o uso de um objeto cabeça singular.
O objeto cabeça é configurado pelo JavaScript por trás das cenas para encapsular código definidopelo usuário e armazenar o código nativo do JavaScript que vem pré-empacotado. Código definidopelo usuário é colocado pelo JavaScript dentro do objeto cabeça para execução. Vamos verificar issocomo pertence ao navegador web.
A seguir, "desenho" alguns valores JavaScript e verificar os valores sendo colocados no objetocabeça window.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var minhaStringVar = 'minhaString';var minhaFuncaoVar = function() {};minhaString = 'minhaString';minhaFuncao = function() {};
console.log('minhaStringVar' in window); //retorna trueconsole.log('minhaFuncaoVar' in window); //retorna trueconsole.log('minhaString' in window); //retorna true
console.log('minhaFuncao' in window); //retorna true
</script> </body> </html>
Você sempre deve ter cuidado quando escreve código JavaScript, isso deve ser escrito no contextodo objeto cabeça. O material remanescente neste capítulo assume que você entendeu o termo"objeto cabeça" é sinônimo de "objeto global".
Nota
O objeto cabeça é o mais alto contexto/escopo disponível no ambiente JavaScript.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 67/117
67
Funções Globais Contidas com o Objeto Cabeça
JavaScript entrega algumas funções pré-definidas. As funções nativas seguintes são consideradasmétodos do objeto cabeça [em um navegador web window.parseInt('500')]. Você pode pensar queessas funções/métodos prontas para uso (do objeto cabeça) providas pelo JavaScript.
decodeURI()decodeURIComponent()encodeURI()encodeURIComponent()eval()isFinite()isNaN()parseFloat()parseInt()
O Objeto Cabeça Contra Propriedades Globais e Variáveis Globais
Não confunda o objeto cabeça com propriedades globais ou variáveis globais contidas com o escopoglobal. O objeto cabeça é um objeto que contêm todos os objetos. Estes termos "propriedadesglobais" ou "variáveis globais" é usado para referir valores diretamente contidos dentro do objetocabeça e não estão especificamente dentro do escopo de outros objetos. Esses valores sãoconsiderados globais porque não importa onde o código atualmente está sendo executado, emtermos de escopo, todo código tem acesso (via cadeia de escopo) para essas propriedades/variáveisglobais.
A seguir, eu coloco uma propriedade foo no escopo global, então acesso essa propriedade de umescopo diferente.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = 'bar'; /* foo é um objeto global e uma propriedade do objeto cabeça/window */
var minhaAp = function() { //lembre funções criam escopovar executa = function() {
//loga o valor bar, foo que é encontrado via cadeia de escopo no objeto cabeçaconsole.log(foo);
}();}
minhaAp();
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 68/117
68
Eu coloquei a propriedade foo fora do escopo global, a função console.log irá retornar undefined.Isto eu demonstro no código de exemplo a seguir.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var minhaFuncao = function() {var foo = 'bar'}; /* foo é agora o escopo de minhaFuncao */
var minhaAp = function() {var executa = function() {
console.log(foo); /* foo é undefined, não mais no escopo global, o erro ocorre */}();
}
minhaAp();
</script> </body> </html>
No ambiente do navegador web, isto é porque métodos de característica global [window.alert()]pode ser invocado de qualquer escopo. O que você precisa tomar de cuidado com isso é que tudo noescopo global está disponível para qualquer escopo, e então toma o título de "variável global" ou"propriedade global".
Nota
Ecxiste um aspecto de diferença entre usar var e não usar var no escopo global (propriedadesglobais contra variáveis globais).
Referenciando o Objeto Cabeça
Existem tipicamente dois caminhos para referenciar o objeto cabeça. O primeiro caminho ésimplesmente referenciar o nome dado ao objeto cabeça (no navegador web isto pode ser window).O segundo caminho é usar a palavra chave this no escopo global. Cada um deles é detalhado nocódigo a seguir.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = 'bar';
windowRef1 = window;windowRef2 = this;
console.log(windowRef1, windowRef2); //loga a referência para o objeto windowconsole.log(windowRef1.foo, windowRef2.foo); //loga 'bar', 'bar'
</script> </body> </html>
No código anterior, nós explicitamos uma referência para o armazenamento do objeto cabeça emduas variáveis que então são usadas para ganhar acesso a variável global foo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 69/117
69
O Objeto Cabeça é Subentendido e Tipicamente Não Referenciado Explicitamente
Tipicamente uma referência para o objeto cabeça não é usado porque é subentendido. Por exemplo,no ambiente do navegador web, window.alert e alert() são essecialmente a mesma sentença.JavaScript preenche os espaços em branco aqui. Porque o objeto window (objeto cabeça) é o último
objeto checado na cadeia de escopo por um valor, o objeto window é essencialmente sempresubentendido. A seguir, alavancamos a função alert() que está contida no escopo global.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = { // window é subentendido aqui, window.foometodoFoo: function() {
alert('foo' + 'bar'); //window é subentendido aqui, window.alertwindow.alert('foo' + 'bar'); //window é explicitamente usado, com o mesmo efeito
}}
foo.metodoFoo(); //window é subentendido aqui, window.foo.metodoFoo()
</script> </body> </html>
Tenha certeza de entender que este objeto cabeça é subentendido, mesmo quando nãoexplicitamos para inclui-lo, porque o objeto cabeça é a última parada na cadeia de escopo.
Nota
Ser explicito (window.alert() contra alert() custa um pouco mais para à eficiência (quão rápido o
código é executado). É mais rápido se você confiar na cadeia de escopo sozinha e evitar explicitar areferência para o objeto cabeça mesmo se você sabe a propriedade que quer é contida no escopoglobal.
Capítulo 6
A Palavra Chave this
Visão Conceitual do this e Como Ele Refe para Objetos
Quando uma função é criada, a palavra chave chamada this é criada (por trás das cenas), que linca
para o objeto em que a função opera. Dito de outra forma, this é disponível ao espoco da função,
ainda é uma referência para o objeto em que esta função é uma/um propriedade/método.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 70/117
70
Vamos dar uma olhada no objeto cody do Capítulo 1 novamente:
<!DOCTYPE html> <html lang="pt-br"> <body> <script>
var cody = {
vivo : true,
idade : 33,
sexo : 'masculino',
getSexo : function(){return cody.sexo;}
};
console.log(cody.getSexo());
</script> </body> </html>
Observe como dentro da função getSexo, nós estamos acessando a propriedade sexo usando a
notação de ponto (cody.sexo) no próprio objeto cody. Isto pode ser reescrito usando this para
acessar o objeto cody porque this aponta para o objeto cody.
<!DOCTYPE html> <html lang="pt-br"> <body> <script>
var cody = {
vivo : true,
idade : 33,
sexo : 'masculino',
getSexo : function(){return this.sexo;}
};
console.log(cody.getSexo());
</script> </body> </html>
O this usado em this.sexo simplesmente refere-se ao objeto cody em que a função está operando.
O tópico do this pode ser confuso, mas não deve ser. Apenas lembre que, em geral, this é usado
dentro de funções para referir ao objeto em que a função está operando, como oposto a função
propriamente [exceções incluem usar a palavra chave new ou call() e apply()].
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 71/117
71
Notas
A palavra chave this parece e age como qualquer outra variável, a exceção é que você não pode
modificar.
Como oposto aos argumentos e quaisquer parâmetros enviados para a função, this é uma palavra
chva (não uma propriedade) na chamada/ativação do objeto.
Como o Valor de this é Determinado?
O valor de this, passado para todas as funções, é baseado no contexto que a função é chamada no
tempo de execução. Atenção aqui, porque this é uma das peculiaridades que você precisa
memorizar.
O objeto meuObjeto no código a seguir recebe uma propriedade chamada digaFoo, que aponta para
a função digaFoo. Quando digaFoo é chamada do escopo global, this refere-se ao objeto window.Quando é chamado como um método, this refere-se ao meuObjeto.
Desde que meuObjeto possui uma propriedade chamada foo, esta propriedade é usada.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = 'foo';
var meuObjeto = {foo: 'Eu sou meuObjto.foo'};
var digaFoo = function() {
console.log(this['foo']);
};
//dá a meuObjeto uma propriedade digaFoo e tem ela apontada para a função digaFoo
meuObjeto.digaFoo = digaFoo;
meuObjeto.digaFoo(); //loga 'Eu sou meuObjeto.foo'
digaFoo(); //loga 'foo'
</script> </body> </html>
Tenha certeza que você passou em torno de funções, ou possui múltiplas referências para uma
função, você percebe que o valor de this irá mudar dependendo do contexto em que você chama a
função.
Nota
Todas as variáveis exceto this e arguments seguem o escopo léxico.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 72/117
72
A Palavra Chave this Refere-se ao Objeto Cabeça em Funções Aninhadas
Você pode estar se perguntando com o que acontece ao this quando é usado dentro de uma função
que é contida dentro de outra função. A má notícia é em ES3, this perde seu caminho e refere-se ao
objeto cabeça (objeto window no navegador web), em vez do objeto em que a função é definida.
No código a seguir, this dentro de func2 e func3 perde seu caminho e não se refere ao meuObjeto
mas ao objeto cabeça.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {
func1: function() {
console.log(this); //loga meuObjeto
var func2 = function() {console.log(this) //loga window, e fará isso deste ponto em diante
var func3 = function() {
console.log(this); //loga window como isso é o objeto cabeça
}();
}();
}
}
meuObjeto.func1();
</script> </body> </html>
A boa notícia aqui é que isso pode ser resolvido no ES5. Por agora, você deve ter cuidado com esta
situação, especialmente quando você inicia passando funções em torno como valores para outras
funções.
Considere o código a seguir e o que acontece quando passamos uma função anônima para
foo.func1. Quando uma função anônima é chamada dentro de foo.func1 (uma função dentro de
uma função) o valor this dentro da função anônima será uma referência para o objeto cabeça.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = {
func1:function(bar) {
bar(); //loga window, não foo
console.log(this); //a palavra chave this será uma referência para o objeto foo
}
}
foo.func1(function(){console.log(this)});
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 73/117
73
Agora você nunca irá esquecer: o valor this será sempre uma referência para o objeto cabeça
quando sua função é encapsulada dentro de outra função ou invocada com o contexto de outra
função (novamente, isto é resolvido no ES5).
Trabalhando em Torno da Questão da Função Aninhada Alavancando a Cadeia deEscopo
Então este valor this não pode ser perdido, você pode simplesmente usara a cadeia de escopo paramanter uma referência para this na função parente. O código a seguir demonstra como, usando umavariável chamada que, e alavancando seu escopo, nós podemos manter um caminho melhor para afunção em contexto.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {minhaPropriedade: 'Eu não posso ver a luz',meuMetodo : function(){
var que = this; /*armazena uma referência para this (meuObjeto) no escopomeuMetodo */
var funcaoDeAjuda function() { //função filha//loga 'Eu não posso ver a luz' via cadeia de escopo porque que = thisconsole.log(que.minhaPropriedade); //loga 'Eu não posso ver a luz'console.log(this); //logaria window, se não usassemos "que"}();
}}meuObjeto.meuMetodo(); //invoca meuMetodo
</script> </body> </html>
Controlando o Valor de this Usando call() ou apply()
O valor de this é normalmente determinado no contexto em que a função é chamada (excetoquando a palavra chave new é usada – mais sobre isso em um minuto), mas você pode
sobrescrever/controlar o valor de this usando apply() ou call() para definir que objeto this apontaquando invocamos uma função. Usando esses métodos é como dizer "Ei, chame a função X mas digaa função para usar o objeto Z como valor para "this". Fazendo isso, o caminho padrão em queJavaScript determina o valor de this é sobrescrito.
A seguir, nós criamos um objeto e uma função. Nós depois invocamos a função via call() então ovalor de this dentro da função usa meuObjeto como seu contexto. As sentenças dentro da funçãominhaFuncao irão depois popular meuObjeto com propriedades ao invés popular o objeto cabeça.Nós alteramos o objeto ao qual this (dentro de minhaFuncao) referencia.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 74/117
74
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {};
var minhaFuncao = function(param1, param2) {
//configurado via call() 'this' aponta para meuObjeto quando a função é invocadathis.foo = param1;this.bar = param2;console.log(this) //loga Object {foo = 'foo', bar = 'bar'}
};
minhaFuncao.call(meuObjeto, 'foo', 'bar'); /*função invocada, configura o valor de this parameuObjeto*/
console.log(meuObjeto) //loga Object {foo = 'foo', bar = 'bar'}
</script> </body> </html>
No exemplo anterior, estamos usando call(), mas apply() poderia ser usado muito bem. A diferençaentre os dois é como os parâmetros para a função são passados. Usando call(), os parâmetros sãovalores separados por vírgula. Usando apply(), os valores de parâmetros são passados dentro de umvetor. A seguir, é a mesma ideia, mas usando apply().
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = {};
var minhaFuncao = function(param1, param2) {//configurado via call() 'this' aponta para meuObjeto quando a função é invocadathis.foo = param1;this.bar = param2;console.log(this) //loga Object {foo = 'foo', bar = 'bar'}
};
minhaFuncao.apply(meuObjeto, ['foo', 'bar']); /*função invocada, configura o valor de this parameuObjeto*/
console.log(meuObjeto) //loga Object {foo = 'foo', bar = 'bar'}
</script> </body> </html>
O qua você precisa tomar cuidado aqui é que você pode sobrescrever o caminho padrão em queJavaScript determina o valor de this em um escopo de funções.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 75/117
75
Usando a Palavra Chave this Dentro de Uma Função Construtora Definida porUsuário
Quando uma função é invocada com a palavra chave new, o valor de this – como é sentenciado noconstrutor – refere-se a instância própria. Dito de outra forma: em uma função construtora, nóspodemos alavancar o objeto via this antes de o objeto ser atualmente criado. Neste caso, o valorpadrão de this muda em um caminho não como sundo call() ou apply().
A seguir, configuramos a função construtora Pessoa que usa this para referenciar um objeto sendocriado. Quando uma instância de Pessoa é criada, this.nome irá referenciar o novo objeto criado ecolocar uma propriedade chamada nome no novo objeto com um valor do parâmetro (nome)passado para a função construtora.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Pessoa = function(nome) {
this.nome = nome || 'john doe'; //isto irá referenciar para a instância criada}
var cody = new Pessoa('Cody Lindley'); //cria uma instância baseada no construtor Pessoa
console.log(cody.nome); //loga 'Cody Lindley'
</script> </body> </html>
Novamente this refere ao "objeto que irá ser" quando a função construtora é invocada usando apalavra chave new. Nós não usamos a palavra chave new, o valor de this pôde ser o contexto em
que Pessoa é invocado – neste caso o objeto cabeça. Vamos examinar este cenário.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Pessoa = function(nome) {this.nome = nome || 'john doe';
}
var cody = Pessoa('Cody Lindley'); //observe que não usamos 'new'
//console.log(cody.nome); //erro, o valor atualmente está configurado como window.nome
console.log(window.nome); //loga 'Cody Lindley'</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 76/117
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 77/117
77
Capítulo 7
Escopo e Fechamentos
Visão Conceitual de Escopo JavaScript
Em JavaScript, escopo é o contexto em que o código é executado, e aqui esxistem três tipos deescopo: escopo global, escopo local (algumas vezes referido como "escopo de função"), e escopo deavaliação.
Código definido usando var dentro de uma função é de escopo local, e é somente "visível" paraoutras expressões nesta função, que inclui código dentro de qualquer função filha/aninhada.Variáveis definidas no escopo global podem ser acessadas de qualquer lugar porque este é o maiornível/última parada na cadeia de escopo.
Examine o código a seguir e tenha certeza de entender que cada declaração de foo é única por causado escopo.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = 0; //escopo globalconsole.log(foo); //loga 0
var minhaFuncao = function() {
var foo = 1; //escopo local
console.log(foo); //loga 1
var minhaFuncaoAninhada = function() {
var foo = 2; //escopo local
console.log(foo); //loga 2}();
}();
eval('var foo = 3; console.log(foo);'); //eval() escopo
</script> </body> </html>
Por favor observe que cada variável foo contém diferentes valores porque cada um é definido emum escopo especificamente definido.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 78/117
78
Notas
Um número ilimitado de função e escopos de avaliação foram podem ser criados, enquanto umescopo global é usado pelo ambiente JavaScript.
O escopo global é a última parada na cadeia de escopos.
Funções que contém funções criam a pilha de execução de escopos.Estas pilhas que são encadeiadas juntas são também referidas como cadeia de escopo.
JavaScript Não Tem Escopo de Bloco
Desde sentenças lógicas [if (){}] e sentenças de loop (for) não criam um escopo, variáveis podemsobrescrever umas as outras. Examine o código a seguir e tenha certeza que compreende que osvalores de foo são redefinidos assim que o programa executa o código.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = 1; //foo = 1
if (true) {foo = 2; //foo = 2for(var i = 3; i <= 5; i++) {
foo = i; //foo = 3,4, então 5console.log(foo); //loga 3,4,5
}
}
</script> </body> </html>
Então foo está mudando assim que o código é executado porque JavaScript não tem escopo debloco – somente escopo de função, global ou escopo de avaliação.
Usar var Dentro de Funções para Declarar Variáveis e Evitar Pegadinhas de
Escopo
JavaScript irá declarar qualquer variável mesmo sem a declaração var (mesmo aquelas contidas emuma função ou funções encapsuladas) para estar no escopo global em vez do escopo localintencionado. Dê uma olhada no código a seguir e perceba que sem o uso de var para declarar bar, avariável é atualmente definida no escopo global e não no escopo local, como deveria ser.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 79/117
79
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = function() {var boo = function() {
bar = 2; //var não é usado, então bar é colocado no escopo global em window.bar
}();}();
console.log(bar); //loga 2, porque bar está no escopo global
//Opostamente
var foo = function() {var boo = function() {
var doo = 2;}();
}();
console.log(doo); //loga undefined, doo está no escopo da função boo, erros acontecem
</script> </body> </html>
O cuidado aqui é que você pode sempre usar var quando definindo variáveis dentro de uma função.Isto previne você de lidar com problemas de potenciais escopos confusos. A exceção para essaconvenção, é claro, é quando você deseja criar ou mudar propriedades no escopo global a partir dedentro de uma função.
A Cadeia de Escopo (Escopo Léxico)
Existe uma cadeia de pesquisa que é seguida quando JavaScript procura por um valor associado comuma variável. Esta cadeia é baseada na hierarquia do escopo. No código a seguir, eu estouregistrando o valor de digaOi de func2 do escopo de função.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var digaOi = 'Oi';
var func1 = function() {var func2 = function() {console.log(digaOi); //escopo func2, mas encontra digaOi no escopo global
}();}();
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 80/117
80
Como é o valor de digaOi encontrado quando ele não está contido dentro do escopo da funçãofunc2? JavaScript procura primeiro na função func2 por uma variável chamada digaOi. Nãoencontrando em func2, procura pela função parente de func2, func1. A variável digaOi não éencontrada no escopo de func1, de outro modo, então JavaScript continua até o escopo global ondedigaOi é encontrada, então nesse ponto o valor de digaOi é entregue. Se digaOi não fosse definida
no escopo global, undefined seria retornado pelo JavaScript.
Este é um conceito importante a se entender. Vamos examinar outro código de exemplo. A seguir,nós pegamos três valores de três escopos diferentes.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var x = 10;var foo = function() {
var y = 20;var bar = function() {
var z = 30;console.log(z + y + x); //z é local, y e z são encontrados na cadeia de escopo}();
}
foo(); //loga 60</script> </body> </html>
O valor para z é local para a função bar e o contexto em que console.log é invocado, o valor para y
na função foo, que é parente de bar(), e o valor para x estão no escopo global. Todos esses são
acessíveis via cadeia de escopo. Tenha certeza que você entendeu esse referenciamento de variáveis
na função bar que checa todos os caminhos na cadeia de escopo para a variável referenciada.
Nota
A cadeia de escopo, se você pensar sobre ela, não é diferente da cadeia de protótipo. Ambas são
simplesmente um caminho para checar um valor sistematicamente em um conjunto hierárquico de
localizações.
A Cadeia de Escopo Retorna o Primeiro Valor EncontradoNo código a seguir, a variável chamada x existe no mesmo escopo em que é examinada com
console.log. Este valor "local" de x é usado, e alguém talvez possa dizer que são sombras, ou
mascaras, as variáveis identicamente nomeadas como x encontradas na cadeia de escopo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 81/117
81
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var x = false;
var foo = function() {
var x = false;
bar = function() {
var x = true;
console.log(x); //o escopo local de x é o primeiro então ele mascara o resto
}();
}
foo(); //loga true
</script> </body> </html>
Lembre-se que a pesquisa de escopo termina quando a variável é encontada no link mais próximo
disponível na cadeia, mesmo se a mesma variável é usada mais acima na cadeia.
Escopo é Determinado Durante a Definição da Função, e Não na InvocaçãoDesde que funções determinam escopo e funções podem ser passadas em torno como qualquer
valor JavaScript, alguém pode pensar que essa depreciação da cadeia de escopo é complicada. É
muito simples. A cadeia de escopo é decidida baseada na localização de uma função durante adefinição, não durante a invocação. Isto também é chamado de escopo léxico. Pense muito e
duramente sobre isso, a maioria das pessoas tropeçam muito sobre isso no código JavaScript.
A cadeia de escopo é criada antes de você invocar uma função. Por causa disso, nós podemos criar
fechamentos. Por exemplo, nós podemos ter uma função retornando uma função aninhada para o
escopo global, ainda nossa função pode acessar, via cadeia de escopo, isto é o escopo de funções
parente.
A seguir, nós definimos a funcaoParente que retorna uma função anônima, e nós chamamos a
função retornada do escopo global. Por causa de nossa função anônima ser definida para ser contidaem funcaoParente, ela continua a ter acesso ao escopo da funcaoParente quando é invocada. Isto é
chamado fechamento.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 82/117
82
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var funcaoParente = function() {
var foo = 'foo';
return function() { //função anônima sendo retornada
console.log(foo); //loga 'foo'
}
}
//funcaoAninhada refere-se a função aninhada retornada da funcaoParente
var funcaoAninhada = funcaoParente();
funcaoAninhada(); //loga foo porque a função retornada acessa foo via cadeia de escopo
</script> </body> </html>
O cuidado que você deve ter aqui é que a cadeia de escopo é determinada durante a definição –
literalmente no momento em que o código é escrito. Passar em torno de funções dentro do seu
código não irá mudar a cadeia de escopo.
Fechamentos são Causados via Cadeia de EscopoPegue o que você aprendeu sobre cadeia de escopo e pesquisa de escopo neste capítulo, e
fechamento não será complicado de entender. A seguir, nós criamos uma função chamadacontagemDoZero. Esta função atualmente retorna uma referência para a função filha contida dentro
dela. Quando esta função filha (função aninhada) é invocada, continua tendo acesso ao escopo da
função parente por causa da cadeia de escopo.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var contagemDoZero = function() {
var contagem = 0;
return function() { //retorna a função aninhada filha quando contagem é invocada
return ++contagem; /*contagem é definida acima na cadeia de escopo, na função parente*/
};
}(); //invoca imediatamente, retorna a função aninhada
console.log(contagemDoZero()); //loga 1
console.log(contagemDoZero()); //loga 2
console.log(contagemDoZero()); //loga 3
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 83/117
83
Cada vez que contagem é invocada, a função anônima contida na (e retornada da) função contagem
continua tendo acesso ao escopo da função parente. Esta técnica, facilitada via cadeia de escopo, é
um exemplo de fechamento.
Nota
Se você sentir que simplifiquei muito fechamentos, você está correto. Mas o fiz por um motivo,
acredito que partes importantes surgem de uma sólida compreensão de funções e escopo, não
necessariamente as complexibilidades do contexto de execução.
Capítulo 8
Função (Propriedade prototype)
Visão Geral da Cadeia de ProtótipoA propriedade prototype é um objeto criado pelo JavaScript para cada instância Function().
Especificamente, ele liga a instância do objeto criado com a palavra chave new de volta para a
função construtora que a criou. Isto é feito para que então estas instâncias possam compartilhar, ou
herdar, métodos e propriedades comuns. Importante, o compartilhamento ocorre durante a procura
de propriedade. Lembre-se do Capítulo 1 que cada vez que você procurava ou acessava a
propriedade em um objeto, a propriedade era pesquisada dentro do objeto bem como na cadeia de
protótipo.
Nota
O objeto prototype é criado para cada função independentemente de você intencionar usar a
função como um construtor.
A seguir, eu construo um vetor do construtor Array(), e depois eu invoco o método join().
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = new Array('foo', 'bar');
console.log(meuVetor.join()); //loga 'foo, bar'
</script> </body> </html>
O método join não é definido como uma propriedade da instância do objeto meuVetor, mas de
alguma forma nós temos acesso ao join() como se fosse. Este método é definido em algum lugar,
mas onde? Bem, isto é definido como uma propriedade prototype do construtor Array(). Desde que
join() não é encontrado dentro da instância do objeto vetor, JavaScript procura na cadeia de
protótipo por um método chamado join().
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 84/117
84
Tudo bem, então porque as coisas funcionam desta maneira? Realmente, isto é sobre eficiência e
reuso. Por que cada instância de vetor criada da função construtora vetor possui um único método
definido join() quando join() sempre funcionam do mesmo jeito? Isto faz mais sentido para todos os
vetores para alavancar a mesma função join() sem ter que criar uma nova instância da função para
cada instância vetor.
Esta eficiência, que nós falamos é de todo possível porque a propriedade prototype, ligação
prototype, e o prototype pesquisa a cadeia. Neste capítulo, nós quebramos toda essa confusão
sobre atributos da herança de protótipos. Mas verdade seja dita, você pode achar melhor
simplesmente memorizar os mecanismos de como a cadeia hierárquica atualmente funciona. Volte
ao Capítulo 1 se você precisa refrescar em como valores de propriedades são resolvidos.
Quais os Cuidados Sobre a Propriedade prototype?Você deve ter cuidado sobre a propriedade prototype por quatro motivos.
1. O primeiro motivo é que a propriedade prototype é usada pelas funções construtorasnativas (Object(), Array(), Function(), etc...) para habilitar instâncias construtoras para herdar
propriedades e métodos das funções construtoras via propriedade prototype. Se você
deseja entender JavaScript melhor, você precisa entender como JavaScript por si alavanca o
objeto prototype.
2. Quando se cria uma função construtora definida pelo usuário, você pode orquestrar a
herança pelo mesmo caminho dos objetos nativos JavaScript. Mas primeiro, você precisa
entender como funciona.
3. Você pode realmente não gostar da herança de protótipos ou preferir outro padrão para
herança de objeto, mas a realidade é que algum dia você terá de editar ou gerenciar algum
código que usa a herança de protótipo e é melhor saber. Quando isso acontece, você deve
ter cuidado em como a herança de protótipo funciona, bem como pode ser replicada por
desenvolvedores que fazem uso de funções construtoras customizadas.
4. Usando herança de protótipo, você pode criar instâncias de objetos eficientes em que todas
alavancam os mesmos métodos. Como já mencionado, nem todos os objetos vetores, que
são instâncias do construtor Array(), precisam dos seus próprios métodos join(). Todas as
instâncias podem ser alavancadas pelo mesmo método join() porque o método é
armazenado na cadeia de protótipo.
Protótipo é Padrão em Todas as Instâncias function()Todas as funções são criadas do construtor Function(), mesmo se você não invocar diretamente
o construtor Function() (var adiciona = new Function('x', 'y', 'return x + z');) como alternativa usar
a notação literal (var adiciona = function(x, y) {return x + z};).
Quando uma instância de função é criada, ela sempre dá uma propriedade prototype, que é um
objeto vazio. A seguir, nós definimos uma função chamada minhaFuncao, então nós acessamos
a propriedade prototype, que é simplesmente um objeto vazio.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 85/117
85
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var minhaFuncao = function() {};
console.log(minhaFuncao.prototype); //loga object{}
console.log(typeof minhaFuncao.prototype); //loga 'object'
</script> </body> </html>
Tenha certeza que entendeu que a propriedade prototype vem do construtor Function(). Nós
apenas queremos usar a função como uma função construtora definida pelo usuário em que a
propriedade prototype é alavancada, mas isso não muda o fato do construtor Function() dá a
cada instância uma propriedade prototype.
A Propriedade Padrão prototype é um Objecto Object()
Toda essa conversa sobre prototype pode ser meio pesada. Realmente, prototype é somente umobjeto vazio com propriedade chamada "prototype" criado por trás das cenas pelo JavaScript e
feito disponível invocando o construtor Function(). Se você quiser fazer isso manualmente, deve
parecer com algo como isso:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var minhaFuncao = function() {};
minhaFuncao = {}; //adiciona a propriedade prototype e a configura para ser um objeto vazio
console.log(minhaFuncao.prototype); //loga um objeto vazio
</script> </body> </html>
De fato, o código acima funciona muito bem, essencialmente apenas duplicando o que
JavaScript já faz.
Nota
O valor de uma propriedade prototype pode ser configurado para qualquer valor complexo
(objetos) disponíveis no JavaSript. JavaScript irá ignorar qualquer propriedade prototype
configurada como valor primitivo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 86/117
86
Instâncias Criadas de uma Função Construtora são Ligados a Propriedadeprototype do Construtor
Enquanto é apenas um objeto, prototype é especial porque a cadeia de protótipo liga cada
instância a sua propriedade prototype da função construtora. Isto significa que toda vez que um
objeto é criado de uma função construtora usando a palavra chave new (ou quando empacotadoé criado de um valor primitivo), isto adiciona uma ligação escondida entra a instância do objeto
criado e a propriedade prototype da função construtora usada para cria-lo. Este link é conhecido
dentro de instâncias como __proto__ [embora seja apenas exposto/suportado via código em
Firefox 2+, Safari, Chrome, e Android]. JavaScript liga isto quando uma função construtora é
invocada e essa ligação permite a cadeia de protótipo ser, bem, uma cadeia. A seguir nós
adicionamos uma propriedade prototype ao construtor nativo Array(), que nós podemos então
acessar de uma instância Array() usando a propriedade __proto__ configurada nesta instância.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//este código somente funciona em navegadores web que suportam o acesso __proto__
Array.prototype.foo = 'foo';
var meuVetor = new Array();
//somente funciona em Firefox 2+, Safari, Chrome, e Android
console.log(meuVetor.__proto__.foo); /*loga foo, porque meuVetor.__proto__ =
Array.prototype*/
</script> </body> </html>
Desde que acessar __proto__ não é parte do padrão oficial ECMA, há mais um caminho
universal para traçar a ligação de um objeto para o objeto prototype herdado, e isto é feito
usando a propriedade constructor. Isto é demonstrado a seguir.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
Array.prototype.foo = 'foo'; //todas as instâncias de Array() agora herdam a propriedade foo
meuVetor = new Array();
//traça foo em um caminho verboso alavancando *.constructor.prototype
console.log(meuVetor.constructor.prototype.foo); //loga foo
//ou, claro, alavanca a cadeia
console.log(meuVetor.foo) //loga foo
//usa a cadeia de protótipo para encontrar a propriedade de Array.prototype.foo
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 87/117
87
No código acima, a propriedade foo é encontrada dentro do objeto prototype. Você precisa
entender que isto é possível apenas porque há associação/ligação entre a instância de Array() e
o objeto prototype de Array() (Array.prototype). Simplesmente coloca, meuVetor.__proto__(ou
meuVetor.constructor.prototype) referenciando Array.prototype.
A Última Parada na Cadeia de Protótipo é Object.prototypeDesde que a propriedade prototype é um objeto, a última parada na cadeia de protótipo ou
pesquisa é em Object.prototype. No código a seguir, eu crio meuVetor, que é um vetor vazio. Eu
então tento acessar a propriedade de meuVetor que ainda não foi definida, engajando a
pesquisa de cadeia de protótipo. O objeto meuVetor é examinado pela propriedade foo. Estando
ausente, ele então pesquisa pela propriedade em Array.prototype, mas não está lá. Então o
último lugar a ser pesquisado é Object.prototype. Por causa de não ser definido em qualquer um
dos três objetos, a propriedade é undefined.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = [];
console.log(meuVetor.foo) //loga undefined
/*foo não foi encontrado em meuVetor.foo ou Array.prototype.foo ou Object.prototype.foo,
então é undefined*/
</script> </body> </html>
Tome nota que a cadeia é parada com Object.prototype. A última parada que é pesquisada por
foo foi Object.prototype.
Nota
Cuidado! Qualquer coisa adicionada para Object.prototype vai aparecer em um loop for
A Cadeia de Protótipo Retorna a Primeira Propriedade Encontrada na CadeiaComo a cadeia de escopo, a cadeia de protótipo irá usar o primeiro valor encontrado durante a
pesquisa de cadeia.
Modificando o último código de exemplo, se adicionar o mesmo valor para os objetos
Object.prototype e Array.prototype, e então tentar acessar um valor em uma instância de vetor,o valor retornado pode ser do objeto Array.prototype.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 88/117
88
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
Object.prototype.foo = 'objeto-foo';
Array.prototype.foo = 'vetor-foo';
var meuVetor = [];
console.log(meuVetor.foo); //loga 'array-foo', encontrado em Array.prototype.foo
meuVetor.foo = 'bar';
console.log(meuVetor.foo) //loga 'bar', encontrado em Array.foo
</script> </body> </html>
No código acima, o valor foo em Array.prototype.foo é um sombreamento, ou mascaramento do
valor foo encontrado em Object.prototype.foo. Apenas lembre que esta pesquisa terminaquando a propriedade é encontrada na cadeia, mesmo o nome da propriedade sendo
igualmente usado mais acima na cadeia.
Substituir a Propriedade prototype com um Novo Objeto Remove a PropriedadePadrão do Construtor
É possível substituir o valor padrão de uma propriedade prototype com um novo valor. Fazendo
isso, entretanto, irá eliminar a propriedade padrão constructor encontrada no objeto prototype
"pré-fabricado" - a menos que você especifique um manualmente.
No código a seguir, nós criamos uma função construtora Foo, substituímos a propriedadeprototype com um objeto vazio, e verificamos que a propriedade constructor é quebrada (agora
referencia o construtor menos útil Object()).
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Foo = function Foo(){};
Foo.prototype = {}; //substitui a propriedade prototype com um objeto vazio
var InstanciaFoo = new Foo();
console.log(InstanciaFoo.constructor === Foo); /*loga false, nós quebramos a referência*/
console.log(InstanciaFoo.constructor); //loga Object() não Foo()
//compare com o código onde nós não substituímos o valor prototype
var Bar = function Bar(){};
var InstanciaBar = new Bar();
console.log(InstanciaBar.constructor === Bar); //loga true
console.log(InstanciaBar.constructor); //loga Bar()
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 89/117
89
Se você pretende substituir a propriedade padrão prototype (comum com alguns padrões POO
em JS) configurados pelo JavaScript, você deve ligar novamente juntos a propriedade
constructor que ferencia a função constructor. A seguir, nós alteramos o código, então a
propriedade constructor irá novamente prover uma referência a própria função construtora.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Foo = function Foo(){};
Foo.prototype = {constructor:Foo};
var InstanciaFoo = new Foo();
console.log(InstanciaFoo.constructor === Foo); //loga true
console.log(InstanciaFoo.constructor); //loga Foo()
</script> </body> </html>
Instâncias que Herdam Propriedades do Protótipo Irão Sempre Pegar os ÚltimosValores
A propriedade prototype é dinâmica no sentido que instâncias irão sempre pegar o último valor
do protótipo, indiferente de quando é instanciado, modificado, ou anexado.
No código a seguir, nós criamos uma instância de Foo() chamada InstanciaFoo. Depois, logamos
o valor de x. Então nós atualizamos o valor do protótipo de x e logamos novamente para
encontrar que nossa instância acessou o último valor encontrado no objeto prototype.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Foo = function Foo(){};
Foo.prototype.x = 1;
var InstanciaFoo = new Foo();
console.log(InstanciaFoo.x); //loga 1
Foo.prototype.x = 2;
console.log(InstanciaFoo.x); //loga 2, InstanciaFoo foi atualizada
</script> </body> </html>
Dado como a pesquisa de cadeia funciona, este comportamento não deve ser surpreendente. Se
você está se perguntando, isto funciona do mesmo jeito, ou se independentimente você usar o
objeto padrão prototype, ou sobrescreve-lo com seu próprio. Aqui eu substituo o objeto padrão
prototype para demonstrar este fato:
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 90/117
90
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Foo = function Foo(){};
Foo.prototype = {x:1}; //os logs a seguir continuarão a funcionar
var InstanciaFoo = new Foo();
console.log(InstanciaFoo.x); //loga 1
Foo.prototype.x = 2;
console.log(InstanciaFoo.x); //loga 2, InstanciaFoo foi atualizada
</script> </body> </html>
Substituindo a Propriedade prototype com um Novo Objeto não Atualiza as
Instâncias AntigasVocê pode pensar que pode substituir a propriedade prototype inteiramente a qualquer tempo
e todas as instâncias serão atualizadas, mas isso não é correto. Quando você cria uma instância,
esta instância será amarrada ao prototype que foi "cunhado" no tempo de instanciamento.
Provendo um novo objeto como propriedade prototype não atualiza a conexão entre instâncias
já criadas e o novo prototype.
Mas lembre, como eu sentenciei acima, você pode atualizar ou adicionar para o originalmente
criado objeto prototype e esses valores continuam conectados a primeira instância(s).
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Foo = function Foo(){};
Foo.prototype.x = 1;
var InstanciaFoo = new Foo();
console.log(InstanciaFoo.x); //loga 1, como você pensou que seria
//agora vamos substituir/sobrescrever o objeto prototype com um novo objeto Object()
Foo.prototype = {x:2};
console.log(InstanciaFoo.x); /*loga 1, O QUE?, não poderia logar 1, nós atualizamos prototype*/
/* InnstanciaFoo continua a referenciar a mesma sentença em que o objeto prototype estava quando nós o
instanciamos*/
//cria uma nova instância de Foo()
var NovaInstanciaFoo = new Foo();
//a nova instância é agora amarrada ao novo valor do objeto prototype [x:2]
console.log(NovaInstanciaFoo.x); //loga 2
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 91/117
91
O cuidado chave aqui é que um objeto prototype não pode ser substituído com um novo objeto
uma vez que você inicia a criação de instâncias. Então isto resultará em instâncias que possuem
uma ligação para diferentes protótipos.
Construtores Definidos pelo Usuários Podem Alavancar a Mesma Herança de
Protótipo como Construtores NativosEsperançosamente, neste ponto do capítulo está naufragando em como o JavaScript alavanca a
propriedade prototype por herança (Array.prototype). Este mesmo padrão pode ser alavancado
quando criamos uma função construtora não nativa definida pelo usuário. A seguir, nós
pegamos o clássico objeto Pessoa e imitamos o padrão que o JavaScript usa para herança.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Pessoa = function() {};
/*todas as instâncias Pessoa herdam as propriedades pernas, braços, e o métodocontarMembros */
Pessoa.prototype.pernas = 2;
Pessoa.prototype.braços = 2;
Pessoa.prototype.contarMembros = function() {return this.pernas + this.braços;};
var chuck = new Pessoa();
console.log(chuck.contarMembros()); //loga 4
</script> </body> </html>
No código acima, a função construtora Pessoa() é criada. Nós depois adicionamos propriedades
a propriedade prototype de Pessoa(), que pode ser herdada por todas as instâncias. Então
clramente, no nosso código podemos alavancar a cadeia de protótipo pelo mesmo caminho que
JavaScript alavanca por herança objetos nativos.
Como um bom exemplo de como você pode alavancar isso, você pode criar uma função
construtora em que as instâncias herdam as propriedades pernas e braços se elas não forem
providas como parâmetros.
A seguir, se o construtor Pessoa() receber parâmetros, eles serão usados como propriedades de
instância, mas se um ou mais parâmetros não forem providos há um retorno. Estas propriedades
de instância então sombreiam ou mascaram as propriedades herdadas. Então você tem o
melhor de dois mundos.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 92/117
92
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Pessoa = function (pernas, braços) {
//sombreia o valor prototype
if (pernas !== undefined) {this.pernas = pernas;}
if (braços !== undefined) {this.braços = braços;}
};
Pessoa.prototype.pernas = 2;
Pessoa.prototype.braços = 2;
Pessoa.prototype.contaMembros = function() {return this.pernas + this.braços;};
var chuck = new Pessoa(0, 0);
console.log(chuck.contaMembros()); //loga 0
</script> </body> </html>
Criando Cadeias de Herança (A Intenção Original)Herança de protótipo foi concebida para habilitar cadeias de herança que imitam o padrão de
herança encontrado em linguagens de programação orientadas a objetos tradicionais. Herança é
simlesmente um objeto recebendo acesso a outras propriedades de objetos. Isto é feito
instanciando o objeto que você deseja que herde um valor da propriedade prototype da funçãoque cria o objeto que está fazendo a herança.
Quando isto está feito, existe uma ligação (__proto__) entre os objetos que extendem as
propriedades disponíveis para um objeto sobre a pesquisa de propriedade.
No código a seguir, objetos Chefe herdam de Pessoa(). Isto significa que se uma propriedade não
é encontrada no objeto Chefe, ela será procurada no protótipo da função que cria objetos
Pessoa(). Para ligar a herança, tudo o que você tem que fazer é instanciar uma instância de
Pessoa() como valor para Chefe.prototype (Chefe.prototype = new Pessoa();).
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 93/117
93
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var Pessoa = function() {this.bar = 'bar'};
Pessoa.prototype.foo = 'foo';
var Chefe = function() {this.vai = 'vai'};
Chefe.prototype = new Pessoa();
var cody = new Chefe();
console.log(cody.foo); //loga 'foo'
console.log(cody.vai); //loga 'vai'
console.log(cody.bar); //loga 'bar'
</script> </body> </html>
Tudo o que fizemos no código acima é alavancar um sistema que já está no lugar com objetos
nativos. Considere que Pessoa() não é como o valor padrão Object() para propriedades
prototype. Em outras palavras, isto é exatamente o que acontece quando uma propriedade
prototype, contendo o valor padrão vazio Object(), procura o protótipo da função construtora
que o criou (Object.prototype) para propriedades herdadas.
Caítulo 9
Array()
Visão Geral do Uso de Objetos Array()Um vetor é uma lista de valores ordenados, tipicamente criados com a intenção de se criar um
loop sobre os valores indexados numericamente, começando com o índice zero. O que você
precisa saber é que vetores são conjuntos numericamente ordenados, contra objetos, que tem
nomes de propriedades associados com valores em ordem não numérica. Essencialmente,
vetores usam números como chave de pesquisa, enquanto objetos possuem nomes de
propriedades definidos pelo usuário. JavaScript não tem vetores associativos verdadeiros, mas
objetos podem serem usados para alcançar a funcionalidade dos vetores associativos.
A seguir, eu armazeno quatro strings em meuVetor e eu posso acessa-lo usando um índex
numérico. Eu comparo e constrasto isso a um objeto literal imitando um vetor associativo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 94/117
94
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = ['azul', 'verde', 'laranja', 'vermelho'];
console.log(meuVetor[0]); //loga azul usando o índex 0 para acessar a string em meuVetor
//contra
var meuObjeto = { //vetor associativo, conhecido como objeto em JavaScript
'azul' : 'azul',
'verde' : 'verde',
'laranja' : 'laranja',
'vermelho' : 'vermelho'
};
console.log(meuObjeto['azul']); //loga azul
</script> </body> </html>
Notas
Vetores podem manter qualquer tipo de valores, e esses valores podem ser atualizados ou
apagados a qualquer tempo.
Se você precisa de uma "associação" (vetor associativo), um objeto é a solução mais próxima.
Um Array() é apenas um tipo especial de Object(). Isto é, instâncias Array() são basicamente
instâncias Object() com algumas funções extra (length e um índex numérico interno).
Valores contidos em um vetor são comumente referenciados como elementos.
Parâmetros Array()Você pode passar valores de uma instância vetor para o construtor como parâmetros separados
por vírgula (new Array('foo','bar');). O construtor Array() pode manter 4.294.967.295
parâmetros.
Entretanto, se somente um parâmetro é enviado para o construtor Array(), e esse valor é um
inteiro (1, 123, ou 1.0), então ele será usado para configurar o tamanho (ojeto.length) do vetor,
e não será usado como valor contido com o vetor.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 95/117
95
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var foo = new Array(1, 2, 3);
var bar = new Array(100);
console.log(foo[0], foo[2]); //loga '1 3'
console.log(bar[0], bar.length); //loga 'undefined 100'
</script> </body> </html>
Propriedade e Métodos Array()O objeto Array() possui as seguintes propriedades (não incluindo as propriedades e métodos
herdados):
Propriedades (Array.prototype)
prototype
Instâncias de Objeto Array (Propriedades e Métodos)Instâncias de objetos Array possuem as seguintes propriedades e métodos:
Propriedades de Instância (meuVetor = ['foo', 'bar']; meuVetor.length;):
constructor
index
input
length
Métodos de Instância (meuVetor = ['foo']; meuVetor.pop(););
pop()
push()
reverse()
shift()
sort()
splice()
unshift()
concat()
join()
slice()
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 96/117
96
Criando VetoresComo a maioria dos objetos em JavaScript, um objeto vetor pode ser criado usando o operador
new em conjunção com o construtor Array(), ou usando a sintaxe literal.
A seguir, eu crio o vetor meuVetor1 com valores predefinidos usando o construtor Array(), e
depois meuVetor2 usando a sintaxe literal:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//construtor Array()
var meuVetor1 = new Array('azul', 'verde', 'laranja', 'vermelho');
console.log(meuVetor1); //loga ['azul', 'verde', 'laranja', 'vermelho']
//vetor com notação literal
var meuVetor2 = ['azul', 'verde', 'laranja', 'vermelho'];
console.log(meuVetor2); //loga ['azul', 'verde', 'laranja', 'vermelho']
</script> </body> </html>
É mais comum ver um vetor definido usando a sintaxe literal, mas deve-se ter consciência de
que este atalho é simplesmente ocultar o uso do construtor Array().
Notas
Na prática, o vetor literal é tipicamente tudo que você sempre precisará.
Indiferente de como o vetor é definido, se você não prover qualquer valor predefinido para o
vetor, o vetor continuará sendo criado, mas simplesmente não conterá valores.
Adicionando e Atualizando Valores em VetoresUm valor pode ser adicionado a um vetor em qualquer índice, a qualquer tempo. A seguir, nós
estamos adicionando um valor para o índice numérico 50 de um vetor vazio. O que dizer sobre
todos os índices antes de 50? Bem, como eu disse você pode adicionar um valor para um vetor
em qualquer índice, a qualquer tempo. Mas, se você adicionar um valor para o índice numérico
50 de um vetor vazio, JavaScript irá preencher todos os índices necessários antes dele comvalores undefined.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = [];
meuVetor[50] = 'azul';
console.log(meuVetor.length); /*loga 51 (0 é contado) porque JS criou valores de 0 até 50 antes
de "azul" */
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 97/117
97
Adicionalmente, considerando a natureza dinâmica do JavaScript e o fato de que JavaScript não
é fortemente tipado, um valor vetor pode ser atualizado a qualquer tempo e o valor contido no
índice pode ser qualquer valor legal no JavaScript. A seguir, eu mudo o valor no índice numérico
50 para um objeto.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = [];
meuVetor[50] = 'azul';
meuVetor[50] = {'cor' : 'azul'}; //muda o tipo do objeto de uma string para um objeto Object()
//usando colchetes para acessar o índice no vetor, depois a propriedade azul
console.log(meuVetor[50]['cor']); //loga azul
//usando a notação de ponto
console.log(meuVetor[50].cor); //loga azul
</script> </body> </html>
Length contra IndexUm vetor inicia indexando valores em 0. Isto significa que o primeiro slot para segurar um valor
no vetor parece com meuVetor[0]. Isto pode ser um pouco confuso - se eu criar um vetor com
um único valor, o índice do valor é 0 enquanto o tamanho do vetor é 1. Tenha certeza que você
entende que o tamanho de um vetor representa o número de valores contidos com o vetor,enquanto o índice numérico do vetor inicia em zero.
A seguir, o valor de string azul é contido no vetor meuVetor no índice numérico 0, mas desde
que o vetor contêm um valor, o tamanho do vetor é 1.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = ['azul'] //o índice 0 contém o valor de string 'azul'
console.log(meuVetor[0]); //loga 'azul'
console.log(meuVetor.length); //loga 1
</script> </body> </html>
Definindo Vetores com Tamanho PredefinidoComo eu mencionei anteriormente, passando um simples parâmetro inteiro para o construtor
Array(), é possível predefinir o tamanho do vetor(es), ou o número de valores que ele contém.
Neste caso, o construtor faz uma exceção e assume que você quer configurar o tamanho do
vetor e não pré-popular o vetor com valores.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 98/117
98
A seguir, nós configuramos o vetor meuVetor com o tamanho predefinido 3. Novamente, nós
estamos configurando o length de um vetor, e não passando para ele um valor a ser armazenado
no índice 0.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = new Array(3);
console.log(meuVetor.length); //loga 3, porque nós estamos passando um parâmetro numérico
console.log(meuVetor[0]); //loga undefined
</script> </body> </html>
Notas
Provendo um tamanho predefinido irá dar para cada índice numérico, acima do tamanho
especificado, um valor associado de undefined.
Você pode estar se perguntando pela possibilidade de criar um vetor predefinido contendo
apenas um valor numérico. Sim, é possível – usando a forma literal var meuVetor = [4].
Configurando o Tamanho de um Vetor Pode Adicionar ou Remover ValoresA propriedade length de um objeto vetor pode ser usada para pegar ou configurar o tamanho de
um vetor.
Como mostrado anteriormente, configurando o tamanho maior do que o número de valores
contidos atualmente no vetor irá adicionar valores undefined para o vetor. O que você talveznão espera é que você atualmente pode remover valores de um vetor configurando o valor do
tamanho para um número menor que o de valores contidos no vetor.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = ['azul','verde','laranja','vermelho'];
console.log(meuVetor.length); //loga 4
meuVetor.length = 99;
console.log(meuVetor.length); //loga 99, lembre-se nós configuramos o tamanho, não o índice
meuVetor.length = 1; //removemos todos, mas um valor, então tudo a partir de [1] se foi
console.log(meuVetor[1]); // loga undefined
console.log(meuVetor); //loga '["azul"]'
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 99/117
99
Vetores Contendo Outros Vetores (Vetores Multidimensionais)Desde que um vetor pode segurar qualquer valor JavaScript válido, um vetor pode conter outros
vetores. Quando isto é feito, o vetor contendo vetores encapsulados é considerado um vetor
multidimensional. Acessar vetores encapsulados é feito pelo encadeamento de colchetes. A
seguir, nós estamos criando um vetor literal que contém um vetor, dentro dele nós criamos
outro vetor literal, dentro dele criamos outro vetor literal, contendo o valor de string no índice 0.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = [[[['4ª Dimensão']]]];
console.log(meuVetor[0][0][0][0]); //loga '4ª Dimensão'
</script> </body> </html>
O código acima é bobo, mas você deve tomar cuidado com o fato de que vetores podem conter
outros vetores e você pode acessar vetores encapsulados indefinidamente.
Loop Sobre um Vetor, para Frente e para TrásO caminho simplificado (e indiscutivelmente mais rápido) de fazer um loop sobre um vetor é
usar o loop while.
A seguir, nós fazemos um loop que varre do ínico ao fim o índice.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = ['azul','verde','laranja','vermelho'];
var tamanhoDoMeuVetor = meuVetor.length; /*cria o cache do tamanho do vetor, para evitar
pesquisa desnecessária*/
var contador = 0; //configura o contador
while (contador < tamanhoDoMeuVetor) { /*executa se o contador é menor que o tamanho do
vetor*/
console.log(meuVetor[contador]); //loga 'azul','verde','laranja','vermelho'
contador++; //adiciona 1 ao contador
}
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 100/117
100
E agora fazemos o loop do fim do índice para o início.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuVetor = ['azul','verde','laranja','vermelho']
var tamanhoDoMeuVetor = meuVetor.length;
while (tamanhoDoMeuVetor--) { //se o tamanho não é zero, faz o loop e subtraí 1
console.log(meuVetor[tamanhoDoMeuVetor]); //loga 'vermelho','laranja','verde','azul'
}
</script> </body> </html>
Se você está se perguntando sobre o porquê eu não estou mostrando loops for, é porque loops
while possuem poucas partes de movimentação e acredito serem fáceis de ler.
Capítulo 10
String()
Visão Geral do Objeto Usando String()A função construtora String() é usada para criar objetos string e valores primitivos de string.
No código a seguir, eu detalho a criação de valores string no JavaScript.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//cria o objeto string usando a palavra chave new e o construtor String()
var objetoString = new String('foo');
console.log(objetoString); //loga foo {0 = 'f', 1 = 'o', 2 = 'o'}
console.log(typeof objetoString); //loga 'object'
//cria uma string literal/primitiva usando diretamente o construtor String
var objetoStringSemApalavraChaveNew = String('foo'); //sem a palvra chave new
console.log(objetoStringSemApalavraChaveNew); //loga 'foo'
console.log(typeof objetoStringSemApalavraChaveNew); //loga 'string'
//cria uma string literal/primitiva (o construtor é a lavancado por trás das cenas)
var stringLiteral = 'foo';
console.log(stringLiteral); //loga foo
console.log(typeof stringLiteral); //loga 'string'
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 101/117
101
Parâmetros StringA função construtora String() leva um parâmetro: o valor da string sendo criada.
A seguir, nós criamos a variável, objetoString, para conter o valor de string 'foo'.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//cria o objeto string
var objetoString = new String('foo');
console.log(objetoString); //loga 'foo {0 = "f", 1 = "o", 2 = "o"}'
</script> </body> </html>
Nota
Instâncias do construtor String(), quando usadas com a palavra chave new, produzem um objetocomplexo. Você deve tomar cuidado ao fazer isso (usando números literais/primitivos) por causa
dos problemas potenciais associados com o operador typeof. O operador typeof relata objetos
complexos de string como 'object' ao invés do rótulo primitivo ('string') que você poderia
esperar. Adicionalmente, o valor literal/primitivo é apenas rápido de se escrever e mais conciso.
Propriedades e Métodos String()O objeto string possui as/os seguintes propriedades e métodos (não incluindo propriedades e
métodos herdados):
Propriedades (String.prototype;):
prototype
Métodos (String.fromCharChode();):
fromCharChode
Instância de Objeto String (Propriedades e Métodos)Instâncias de objetos string possuem as/os seguintes propriedades e métodos/.
Propriedades de Instância (var minhaString = 'foo' ; minhaString.length;):
constructor
length
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 102/117
102
Métodos de Instância (var minhaString = 'foo' ; minhaString.toLowerCase();):
charAt()
charCodeAt()
concat()
indexOf()
lastIndexOf()
localeCompare()
match()
quote()
replace()
search()
slice()
split()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
valueOf()
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 103/117
103
Capítulo 11
Number()
Visão Geral do Uso do Objeto Number()A função construtora Number() é usada para criar objetos numéricos e valores primitivos
numéricos.
No código a seguir, eu detalho a criação de valores numéricos no JavaScript.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//cria o objeto objetoNumero usando a palavra chave new e o constructor Number()
var objetoNumero = new Number(1);
console.log(objetoNumero); //loga 1
console.log(typeof objetoNumero) // loga 'object'
//cria um número literal/primitivo usando o construtor number sem new
var objetoNumeroSemNew = Number(1); //sem usar a palavra chave new
console.log(objetoNumeroSemNew); //loga 1
console.log(typeof objetoNumeroSemNew) //loga 'number'
//cria um numero literal/primitivo (o construtor é alavancado por trás das cenas)
var numeroLiteral = 1;
console.log(numeroLiteral); //loga 1
console.log(typeof numeroLiteral); //loga 'number'
</script> </body> </html>
Números Inteiros e de Ponto FlutuanteNúmeros em JavaScript são tipicamente escritos como valores inteiros ou de ponto flutuante.
No código a seguir, eu crio um número primitivo inteiro e um número primitivo de ponto
flutuante. Isto é o uso mais comum de valores de números em JavaScript.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 104/117
104
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var inteiro = 123;
console.log(inteiro); //loga '123'
var pontoFlutuante = 2.123;
console.log(pontoFlutuante); //loga '2.123'
</script> </body> </html>
Nota
Em JavaScript, um valor numérico pode ser um valor hexadecimal ou valor octal, mas isso não é
tippicamente feito.
Parâmetros Number()A função construtora Number() tem apenas um parâmetro: o valor numérico sendo criado. A
seguir, nós criamos um objeto número para o valor 465 chamado numeroUm.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var numeroUm = new Number(465);
console.log(numeroUm); //loga '465{}'
</script> </body> </html>
Nota
Instâncias do construtor Number(), quando usadas com a palavra chave new, produzem um
objeto complexo. Você deve tomar cuidado ao criar valores de números usando o construtor
Number() (use números literais/primitivos) por causa dos potenciais problemas associados com
o operator typeof. O operador typeof relata objetos number como 'object' ao invés do rótulo
primitivo ('number') que você poderiar esperar. O valor literal/primitivo é somente mais conciso.
Propriedades Number()O objeto Number() possui as seguintes propriedades:
Propriedades (Number.prototype;):
MAX_VALUE
MIN_VALUE
NaN
NEGATIVE_INFINITY
POSITIVE_INFINITY
prototype
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 105/117
105
Instância de Objeto Number (Propriedades e Métodos)Instâncias de objetos Number possuem as/os seguintes propriedades e métodos:
Propriedades de Instância (meuNumero = 5 ; meuNumero.constructor;):
constructor
Métodos de Instância (var meuNumero = 1.00324 ; meuNumero.toFixed();):
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()
Capítulo 12
Boolean
Visão Geral do Uso de Objeto Boolean()A função construtora Boolean() pode ser usada para criar objetos booleanos (boolean), bem
como valores primitivos boolean, que representam um valor true (verdadeiro) ou false (falso).
No código a seguir, eu detalho a criação de valores booleanos em JavaScript.
<!DOCTYPE htm> <html lang = "pt-br"> <body> <script>
//cria um objeto booleano usando a palavra chave new e o construtor Boolean()
var meuBooleano1 = new Boolean(false); //usando a palavra chave new
console.log(typeof meuBooleano1); //loga 'object'
/* cria um booleano literal/primitivo usando diretamente o construtor sem new*/
var meuBooleano2 = Boolean(0); //sem a palavra chave new
console.log(typeof meuBooleano2); //loga 'boolean'
//cria um booleano literal/primitive (o construtor é alavancado por trás das cenas)
var meuBooleano3 = false;
console.log(typeof meuBooleano3); //loga 'boolean'
console.log(meuBooleano1, meuBooleano2, meuBooleano3); //loga false false false
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 106/117
106
Parâmetros Boolean()A função construtora Boolean() pega apenas um valor para ser convertido para um valor
booleano (true ou false). Qualquer valor JavaScript válido que não é 0, - 0, null, false, NaN,
undefined, ou uma string vazia (" "), serão convertidos para true. A seguir, nós criamos dois
valores de objetos booleanos. Um true, e outro false.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
// parâmetro passado para Boolean() = 0 = false, então foo = false
var foo = new Boolean(0)
console.log(foo);
//parâmetro passado para Boolean() = Math = true, então bar = true
var bar = new Boolean(Math)
console.log(bar);
</script> </body> </html>
Nota
Instâncias do construtor Boolean(), quando usados com a palavra chave new, produzem um
objeto complex. Você deve evitar a criação de valores booleanos usando o construtor Boolean()
(em vez, use números literais/primitivos) por causa de problemas potenciais associados com o
operador typeof. O operador typeof relata objetos booleanos como 'object', em vez do rótuloprimitivo ('boolean') que você pode esperar. Adicionalmente, valores literais/primitivos são mais
rápidos de se escrever.
Boolean (Propriedades e Métodos)O objeto Boolean() possui as seguintes propriedades:
Propriedades (Boolean.prototype;):
prototype
Instância de Objeto Boolean (Propriedades e Métodos)Instâncias de objetos Boolean possuem as/os seguintes propriedades e métodos:
Propriedades de Instância (var meuBooleano = false; meuBooleano.constructor;):
constructor
Métodos de Instância (var meuBooleano = false; meuBooleano.toString();):
toSource()
toString()
valueOf()
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 107/117
107
Objetos Booleanos Falsos Não Primitivos Convertem Para trueUm objeto booleano falso (em oposição a um valor primitivo) criado do construtor Boolean() é
um objeto, e objetos convertem para true. Então, quando criamos um objeto booleano falso via
construtor Boolean(), o valor próprio é convertido para true. A seguir, eu demonstro como um
objeto booleano falso é sempre "verdadeiro".
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var valorFalso = new Boolean(false);
console.log(valorFalso); //temos um objeto booleano falso, mas o objeto é verdadeiro
if (valorFalso) { //objetos booleanos, mesmo que objetos booleanos falsos, são verdadeiros
console.log('valorFalso é verdadeiro');
}
</script> </body> </html>
Se você precisar converter um valor não booleano em um booleano, apenas use o construtor
Boolean() sem a palavra chave new e o valor retornado será um valor primitivo ao invés de um
objeto booleano.
Algumas Coisas são false (falsas), Todo o Resto é true (verdadeiro)Como já mencionado, mas vale a pena mencionar novamente porque é pertinente para
conversões. Se um valor é 0, -0, null, false, NaN, undefined, ou uma string vazia (" "), é falso
(false). Qualquer valor em JavaScript exceto os valores supracitados serão convertidos para
verdadeiro (true) se usado em um contexto booleano (if (true) {};).
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 108/117
108
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//todos estes retornam um valor falso booleano
console.log(Boolean(0));
console.log(Boolean(-0));
console.log(Boolean(null));
console.log(Boolean(false));
console.log(Boolean(' '));
console.log(Boolean(undefined));
console.log(Boolean(null));
//todos estes retornam um valor verdadeiro booleano
console.log(Boolean(1789));
console.log(Boolean('false')); //'false' como string não é falso como valor booleano
console.log(Boolean(Math));
console.log(Boolean(Array()));
</script> </body> </html>
Capítulo 13
Trabalhando com Valores Primitivos String, Number, e Boolean
Valores Literais/Primitivos são Convertidos para Objetos Quando Propriedades
são AcessadasNão fique mistificado pelo fato que literais string, number, e boolean podem ser tratados como
objetos com propriedades [true.toString()]. Quando esses valores primitivos são tratados comoobjetos pela tentativa de acesso as propriedades, JavaScript irá criar um objeto wrapper
primitivo associado ao construtor, então estas propriedades e métodos do objeto wrapper
podem ser acessados. Assim que as propriedades são acessadas, o objeto wrapper é descartado.
Esta conversão nos habilita a escrever código que pode parecer com valores primitivos, de fato,
um objeto. Verdade seja dita, quando é tratado como um objeto nó código, JavaScript irá
converte-lo em um objeto, então o acesso a propriedade irá funcionar, e depois volta para um
valor primitivo uma vez que o valor é retornado. A chave para entender aqui é o que está
ocorrendo, e o que JavaScript está fazendo por você por trás das cenas.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 109/117
109
String:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//objeto string tratado como um objeto
var objetoString = new String('foo');
console.log(objetoString.length); //loga 3
console.log(objetoString['length']); //loga 3
//string literal/primitiva convertida para um objeto quando tratado como um objeto
var stringLiteral = 'foo';
console.log(stringLiteral.length); //loga 3
console.log(stringLiteral['length']); //loga 3
console.log('bar'.length); //loga 3
console.log('bar'['length']); //loga 3
</script> </body> </html>
Number:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//objeto número tratado como objeto
var numeroObjeto = new Number(1.10023);
console.log(numeroObjeto.toFixed()); //loga 1
console.log(numeroObjeto['toFixed']()); //loga 1
/*número tratado como literal/primitivo convertido para um objeto quando tratado com um
objeto*/
var numeroLiteral = 1.10023;
console.log(numeroLiteral.toFixed()); //loga 1
console.log(numeroLiteral['toFixed']()); //loga 1
console.log((1234).toString()); //loga 1234
console.log(1234['toString']()); //loga 1234
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 110/117
110
Boolean:
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//objeto booleano tratado como um objeto
var objetoBooleano = new Boolean(0);
console.log(objetoBooleano.toString()); //loga 'false'
console.log(objetoBooleano['toString']()); //loga 'false'
//booleano primitivo/literal convertido para um objeto quando tratado como objeto
var booleanoLiteral = false;
console.log(booleanoLiteral.toString()); //loga 'false'
console.log(booleanoLiteral['toString']()); //loga 'false'
console.log((true).toString()); //loga 'true'
console.log(true['toString']()); //loga 'true'
</script> </body> </html>
Nota
Quando acessamos uma propriedade em um número primitivo diretamente (não armazenado
em uma variável), você tem que primeiro avaliar o número antes do valor ser tratado como umobjeto [(1).toString(); ou 1..toString();]. Por que dois pontos? O primeiro ponto é considerado
um numérico decimal, não um operador para acessar propriedades do objeto.
Você Pode Tipicamente Usar Valores Primitivos (String, Number e Boolean)Valores literais/primitivos que representam uma string, número ou booleano são rápidos de
escrever e são mais concisos na forma literal.
Você pode usar o valor literal por causa disso. Adicionalmente, a precisão do operador typeof
depende de como você cria o valor (literal contra invocação do construtor). Se você cria um
objeto string, número, ou booleano, o operador typeof relata o tipo como um objeto. Se vocêusa literais, o operador typeof retorna um nome de string do tipo de valor atual (typeof 'foo'
//retorna 'string').
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 111/117
111
No código a seguir, eu demonstro isso de fato.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//objetos string, número, e booleano
console.log(typeof new String('foo')); //loga 'object'
console.log(typeof new Number(1)); //loga 'object'
console.log(typeof new Boolean(true)); //loga 'object'
//literais/primitivos string, número, e booleano
console.log(typeof 'foo'); //loga 'string'
console.log(typeof 1); //loga 'number'
console.log(typeof true); //loga 'boolean'
</script> </body> </html>
Se o seu programa depende do operador typeof para identificar valores de string, número, ou
booleano em termos destes tipos primitivos, você deve evitar String(), Number(), e Boolean().
Capítulo 14
Null
Visão Conceitual do Uso do Valor nullVocê pode usar null para explicitar que a propriedade de um objeto não contém um valor.
Tipicamente, se uma propriedade é configurada para conter um valor, mas o valor não está
disponível por algum motivo, o valor null pode ser usado para indicar que a referência a
propriedade possui um valor vazio.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
/*a propriedade foo está aguardando por um valor, então configuramos seu valor inicial como
null */
var meuObjeto = {foo: null};
console.log(meuObjeto.foo); //loga 'null'
</script> </body> </html>
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 112/117
112
Nota
Não fique confuso com undefined. undefined é usado pelo JavaScript para dizer à você que algo
está faltando. null é provido então você pode determinar quando um valor é aguardado mas não
está disponível ainda.
typeof Retorna Valores null Como "Objeto"Para uma variável que possui um valor null, o operador typeof retorna 'object'. Se você precisar
verificar um valor null, a solução ideal deve ser ver se o valor é depois igual a null. A seguir, nós
usamos o operador === para especificamente verificar que nós estamos lidando com um valor
null.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var meuObjeto = null;
console.log(typeof meuObjeto); //loga 'object', não é de grande ajuda!
console.log(meuObjeto === null); //loga true, somente para um valor null real
</script> </body> </html>
Nota
Quando verificamos um valor null, sempre use === porque === não diferencia entre null e
undefined.
Capítulo 15
Undefined
Visão Conceitual do Valor undefinedO valor undefined é usado pelo JavaScript em dois caminhos distintamente diferentes.
O primeiro caminho é usado para indicar que uma variável declarada (var foo) não possui valor
atríbuido. O segundo caminho é usado para indicar que uma propriedade de objeto que você
está tentando acessar não foi definida (não foi ainda nomeada), e não é encontrada na cadeia de
protótipo.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 113/117
113
A seguir, eu examino ambos os usos de undefined pelo JavaScript.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
var variavelInicializada; //declara variável
console.log(variavelInicializada); //loga undefined
console.log(typeof variavelInicializada); //confirma que JavaScript retorna undefined
var foo = {};
console.log(foo.bar); //loga undefined, não há propriedade bar no objeto foo
console.log(typeof foo.bar); //confirma que JavaScript retorna undefined
</script> </body> </html>
Nota
É considerado boa prática habilitar JavaScript sozinho para usar undefined. Você nunca deve
definir um valor como undefined, como em foo = undefined. No lugar, null deve ser usado se
você está especificando que um valor de propriedade ou variável não está disponível.
JavaScript ECMAScript 3 (e Superior) Declara a Variável undefined no EscopoGlobal
Diferende de versões anteriores, JavaScript ECMAScript 3 (e superior) possui uma variável global
chamada undefined declarada no escopo global. Por causa de a variável ser declarada, e não
possuir valor atribuído, a variável undefined é configurada para undefined.
<!DOCTYPE html> <html lang = "pt-br"> <body> <script>
//confirma que undefined é uma propriedade do escopo global
console.log(undefined in this); //loga true
</script> </body> </script>
Capítulo 16
Função Math
Visão Conceitual do Objeto Interno MathO objeto Math contêm propriedades estáticas e métodos para matemáticamente lidar com
números ou prover constantes matemáticas (Math.PI). Este objeto é interno do JavaScript, ao
oposto de ser baseado em um constutor Math() que criaria instâncias matemáticas.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 114/117
114
Nota
Você pode estar confuso pelo falo de Math começar com letra maiúscula desde que você não
instanciou nenhum objeto Math. Não se preocupe com isso. Simplesmente tome cuidado que
JavaScript configura o objeto para você.
Propriedades (Math.PI)E
LN2
LN10
LOG2E
LOG10E
PI
SQRT1_2
SQRT2
Métodos (Math.random();):abs()
acos()
asin()
atan()
atan2()
ceil()
cós()
exp()
floor()
log()
max()
min()
pow()
random()
round()
sin()
sort()
tan()
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 115/117
115
Math Não é Uma Função ConstrutoraO objeto Math é diferente dos objetos internos que são instanciados. Math é um objeto fora
criado para armazenar propriedades estáticas e métodos, prontos para serem usados quando se
lida com números. Apenas lembre, não existe caminho para criar uma instância de Math, porque
não há construtor.
Math Possui Constantes que Você Não Pode Aumentar/MutarMuitas das propriedades e constantes de Math não podem ser mutadas. Desde que há uma
partida para a natureza mutável do JavaScript, essas propriedades estão todas em maiúsculas
(Math.PI). Não confunda essas propriedades constantes para funções construtoras por causa da
primeira letra em maiúscula. Elas são simplesmente propriedades de objeto que não podem ser
alteradas.
Nota
Constantes definidas pelo usuário não são possíveis em JavaScript 1.5 ECMAScript 3.
Resumo
Os seguintes pontos resumem o que eu pretendo que você tenha aprendido lendo este livro (e
investigando o código de examplo). Leia cada resumo, e se você não entender o que está sendo
dito, retorne ao tópico do livro.
Um objeto é feito de propriedades nomeadas que armazenam valores.
Quase tudo em JavaScript pode agir como um objeto. Valores complexos são, bem, objetos e
valores primitivos podem ser tratados como objetos. Isto é por quê você pode ouvir as pessoas
disserem que tudo em JavaScript é um objeto.
Objetos são criados por invocação de funções construtoras com a palavra chave new, ou usando
uma expressão literal de atalho.
Funções construtoras são objetos (Function() objetos), então, em JavaScript, objetos criam
objetos.
JavaScript oferece 9 construtores nativos: Object(), Array(), String(), Number(), Boolean(),
Function(), Date(), RegExp() e Error(). Os construtores String(), Number(), e Boolean() são de
duplo propósito a) valores primitivos b) objetos wrapper quando preciso, então estes valoresprimitivos podem agir como objetos quando assim tratados.
Os valores null, undefined, "string", 10, true, e false são valores primitivos, sem uma natureza de
objeto a menos que sejam tratados como objetos.
Quando as funções construtoras Object(), Array(), String(), Number(), Boolean(), Function(),
Date(), RegExp(), e Error() são invocadas usando a palavra chave new, um objeto é criado
conhecido como "objeto complexo" ou "objeto de referência".
"string", 10 , true, e false, em suas formas primitivas, não possuem qualidades de objetos a não
ser que sejam usados como objetos; então JavaScript, por trás das cenas, cria objetos wrappertemporários então seus valores agem como objetos.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 116/117
116
Valores primitivos são armazenados por valor, e quando copiado, são literalmente copiado.
Objetos complexos, na outra mão, são armazenados por referência, e quando copiados, são
copiados por referência.
Valores primitivos são iguais a outros valores primitivos quando seus valores são iguais,
enquanto que objetos complexos são iguais somente quando a referênciapossui o mesmo valor.Isto é: um valor complexo é igual a outro valor complexo quando ambos referenciam o mesmo
objeto.
Devido a natureza dos objetos complexos e referencias, objetos JavaScript possuem
propriedades dinâmicas.
JavaScript é mutável, o que significa que objetos nativos e objetos e propriedades definidos(as)
pelo usuário podem ser manipulados(as) a qualquer tempo.
Get/Set/Update (Pegar/Configurar e Atualizar) propriedades de objetos é feito usando a notação
de ponto ou a notação de chaves. A notação de chaves é conveniente quando o nome da
propriedade do objeto sendo manipulado está na forma de expressão
[Array['prototype']['join'].apply()].
Quando referenciamos propriedades de objetos, uma pesquisa de cadeia é usada para procurar
no objeto que está sendo referenciado pela propriedade; se a propriedade não está lá, a
propriedade é procurada nas funções construtoras pela propriedade prototype. Se não
encontrada lá, pelo fato de prototype segurar um valor de objeto e o valor é criado de um
construtor Object(), a propriedade é procurada na propriedade prototype do construtor Object()
(Object.prototype). Se a propriedade não é encontrada, então a propriedade é determinada
como undefined.
A pesquisa de cadeia de protótipo é como herança (herança de protótipo) que é designada para
ser realizada no JavaScript.
Por causa da propriedade do objeto, a pesquisa de cadeia (herança de protótipo), todos os
objetos são herdados de Object() simplesmente porque a propriedade prototype é, por si só, um
objeto Object().
Funções JavaScript são os cidadãos de primeira classe: funções são objetos com propriedades e
valores.
A palavra chave this, quando usada dentro de uma função, é um caminho genérico para
referenciar o objeto contendo a função.
O valor de this é determinado durante o tempo de execução baseado no contexto em que a
função é chamada.
Usada no escopo global, a palavra chave this referencia o objeto global.
JavaScript usa funções como um caminho para criar um escopo único.
JavaScript prove um escopo global, e é onde todo o código JavaScript existe.
7/23/2019 Aprendendo Orientação a Objetos com JavaScript
http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 117/117
Funções (especialmente, funções encapsuladas) criam uma cadeia de escopo para resolver
pesquisas de variáveis.
A cadeia de escopo é configurada baseada no caminho em que o código é escrito, não
necessariamente pelo contexto em que a função é invocada. Isto permite a função ter acesso ao
escopo em que foi originalmente escrito, mesmo se a função é chamada de um contextodiferente. Este resultado é conhecido como fechamento.
Expressões de funções e variáveis declaradas dentro de uma função sem usar var tornam-se
propriedades globais. Entretanto, sentenças de funções dentro de um escopo de função
continuam definidas no escopo em que foi escrita.
Funções e variáveis declaradas (sem var) no escopo global tornam-se propriedades do objeto
global.
Funções e variáveis declaradas (com var) no escopo global tornam-se variáveis globais.