aprendendo orientação a objetos com javascript

117
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údo Capí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 ........................................................................ 27 Objetos 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

Upload: wwwmundodacanablogspotcom

Post on 11-Feb-2018

226 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Aprendendo Orientação a Objetos com JavaScript

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

Page 2: Aprendendo Orientação a Objetos com JavaScript

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

Page 3: Aprendendo Orientação a Objetos com JavaScript

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

Page 4: Aprendendo Orientação a Objetos com JavaScript

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

Page 5: Aprendendo Orientação a Objetos com JavaScript

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

Page 6: Aprendendo Orientação a Objetos com JavaScript

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>

Page 7: Aprendendo Orientação a Objetos com JavaScript

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.

Page 8: Aprendendo Orientação a Objetos com JavaScript

7/23/2019 Aprendendo Orientação a Objetos com JavaScript

http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 8/117

Page 9: Aprendendo Orientação a Objetos com JavaScript

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.

Page 10: Aprendendo Orientação a Objetos com JavaScript

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.

Page 11: Aprendendo Orientação a Objetos com JavaScript

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.

Page 12: Aprendendo Orientação a Objetos com JavaScript

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>

Page 13: Aprendendo Orientação a Objetos com JavaScript

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()

Page 14: Aprendendo Orientação a Objetos com JavaScript

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>

Page 15: Aprendendo Orientação a Objetos com JavaScript

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.

Page 16: Aprendendo Orientação a Objetos com JavaScript

7/23/2019 Aprendendo Orientação a Objetos com JavaScript

http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 16/117

Page 17: Aprendendo Orientação a Objetos com JavaScript

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>

Page 18: Aprendendo Orientação a Objetos com JavaScript

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.

Page 19: Aprendendo Orientação a Objetos com JavaScript

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.

Page 20: Aprendendo Orientação a Objetos com JavaScript

7/23/2019 Aprendendo Orientação a Objetos com JavaScript

http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 20/117

Page 21: Aprendendo Orientação a Objetos com JavaScript

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.

Page 22: Aprendendo Orientação a Objetos com JavaScript

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').

Page 23: Aprendendo Orientação a Objetos com JavaScript

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.

Page 24: Aprendendo Orientação a Objetos com JavaScript

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.

Page 25: Aprendendo Orientação a Objetos com JavaScript

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.

Page 26: Aprendendo Orientação a Objetos com JavaScript

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.

Page 27: Aprendendo Orientação a Objetos com JavaScript

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>

Page 28: Aprendendo Orientação a Objetos com JavaScript

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");

Page 29: Aprendendo Orientação a Objetos com JavaScript

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.

Page 30: Aprendendo Orientação a Objetos com JavaScript

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.

Page 31: Aprendendo Orientação a Objetos com JavaScript

7/23/2019 Aprendendo Orientação a Objetos com JavaScript

http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 31/117

Page 32: Aprendendo Orientação a Objetos com JavaScript

7/23/2019 Aprendendo Orientação a Objetos com JavaScript

http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 32/117

Page 33: Aprendendo Orientação a Objetos com JavaScript

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.

Page 34: Aprendendo Orientação a Objetos com JavaScript

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';

Page 35: Aprendendo Orientação a Objetos com JavaScript

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.

Page 36: Aprendendo Orientação a Objetos com JavaScript

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() {};

Page 37: Aprendendo Orientação a Objetos com JavaScript

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.

Page 38: Aprendendo Orientação a Objetos com JavaScript

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).

Page 39: Aprendendo Orientação a Objetos com JavaScript

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:

Page 40: Aprendendo Orientação a Objetos com JavaScript

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.

Page 41: Aprendendo Orientação a Objetos com JavaScript

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.

Page 42: Aprendendo Orientação a Objetos com JavaScript

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.

Page 43: Aprendendo Orientação a Objetos com JavaScript

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.

Page 44: Aprendendo Orientação a Objetos com JavaScript

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.

Page 45: Aprendendo Orientação a Objetos com JavaScript

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.

Page 46: Aprendendo Orientação a Objetos com JavaScript

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().

Page 47: Aprendendo Orientação a Objetos com JavaScript

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.

Page 48: Aprendendo Orientação a Objetos com JavaScript

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()

Page 49: Aprendendo Orientação a Objetos com JavaScript

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.

Page 50: Aprendendo Orientação a Objetos com JavaScript

7/23/2019 Aprendendo Orientação a Objetos com JavaScript

http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 50/117

Page 51: Aprendendo Orientação a Objetos com JavaScript

7/23/2019 Aprendendo Orientação a Objetos com JavaScript

http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 51/117

Page 52: Aprendendo Orientação a Objetos com JavaScript

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.

Page 53: Aprendendo Orientação a Objetos com JavaScript

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

Page 54: Aprendendo Orientação a Objetos com JavaScript

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 ().

Page 55: Aprendendo Orientação a Objetos com JavaScript

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')].

Page 56: Aprendendo Orientação a Objetos com JavaScript

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.

Page 57: Aprendendo Orientação a Objetos com JavaScript

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>

Page 58: Aprendendo Orientação a Objetos com JavaScript

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>

Page 59: Aprendendo Orientação a Objetos com JavaScript

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.

Page 60: Aprendendo Orientação a Objetos com JavaScript

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>

Page 61: Aprendendo Orientação a Objetos com JavaScript

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()

Page 62: Aprendendo Orientação a Objetos com JavaScript

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>

Page 63: Aprendendo Orientação a Objetos com JavaScript

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>

Page 64: Aprendendo Orientação a Objetos com JavaScript

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.

Page 65: Aprendendo Orientação a Objetos com JavaScript

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>

Page 66: Aprendendo Orientação a Objetos com JavaScript

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.

Page 67: Aprendendo Orientação a Objetos com 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>

Page 68: Aprendendo Orientação a Objetos com JavaScript

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.

Page 69: Aprendendo Orientação a Objetos com JavaScript

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.

Page 70: Aprendendo Orientação a Objetos com JavaScript

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()].

Page 71: Aprendendo Orientação a Objetos com JavaScript

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.

Page 72: Aprendendo Orientação a Objetos com JavaScript

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>

Page 73: Aprendendo Orientação a Objetos com JavaScript

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.

Page 74: Aprendendo Orientação a Objetos com JavaScript

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.

Page 75: Aprendendo Orientação a Objetos com JavaScript

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>

Page 76: Aprendendo Orientação a Objetos com JavaScript

7/23/2019 Aprendendo Orientação a Objetos com JavaScript

http://slidepdf.com/reader/full/aprendendo-orientacao-a-objetos-com-javascript 76/117

Page 77: Aprendendo Orientação a Objetos com JavaScript

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.

Page 78: Aprendendo Orientação a Objetos com JavaScript

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.

Page 79: Aprendendo Orientação a Objetos com JavaScript

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>

Page 80: Aprendendo Orientação a Objetos com JavaScript

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.

Page 81: Aprendendo Orientação a Objetos com JavaScript

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.

Page 82: Aprendendo Orientação a Objetos com JavaScript

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>

Page 83: Aprendendo Orientação a Objetos com JavaScript

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().

Page 84: Aprendendo Orientação a Objetos com JavaScript

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.

Page 85: Aprendendo Orientação a Objetos com JavaScript

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.

Page 86: Aprendendo Orientação a Objetos com JavaScript

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>

Page 87: Aprendendo Orientação a Objetos com JavaScript

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.

Page 88: Aprendendo Orientação a Objetos com JavaScript

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>

Page 89: Aprendendo Orientação a Objetos com JavaScript

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:

Page 90: Aprendendo Orientação a Objetos com JavaScript

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>

Page 91: Aprendendo Orientação a Objetos com JavaScript

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.

Page 92: Aprendendo Orientação a Objetos com JavaScript

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();).

Page 93: Aprendendo Orientação a Objetos com JavaScript

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.

Page 94: Aprendendo Orientação a Objetos com JavaScript

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.

Page 95: Aprendendo Orientação a Objetos com JavaScript

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()

Page 96: Aprendendo Orientação a Objetos com JavaScript

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>

Page 97: Aprendendo Orientação a Objetos com JavaScript

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.

Page 98: Aprendendo Orientação a Objetos com JavaScript

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>

Page 99: Aprendendo Orientação a Objetos com JavaScript

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>

Page 100: Aprendendo Orientação a Objetos com JavaScript

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>

Page 101: Aprendendo Orientação a Objetos com JavaScript

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

Page 102: Aprendendo Orientação a Objetos com JavaScript

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()

Page 103: Aprendendo Orientação a Objetos com JavaScript

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.

Page 104: Aprendendo Orientação a Objetos com 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

Page 105: Aprendendo Orientação a Objetos com JavaScript

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>

Page 106: Aprendendo Orientação a Objetos com JavaScript

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()

Page 107: Aprendendo Orientação a Objetos com JavaScript

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) {};).

Page 108: Aprendendo Orientação a Objetos com JavaScript

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.

Page 109: Aprendendo Orientação a Objetos com JavaScript

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>

Page 110: Aprendendo Orientação a Objetos com JavaScript

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').

Page 111: Aprendendo Orientação a Objetos com JavaScript

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>

Page 112: Aprendendo Orientação a Objetos com JavaScript

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.

Page 113: Aprendendo Orientação a Objetos com JavaScript

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.

Page 114: Aprendendo Orientação a Objetos com JavaScript

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()

Page 115: Aprendendo Orientação a Objetos com JavaScript

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.

Page 116: Aprendendo Orientação a Objetos com JavaScript

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.

Page 117: Aprendendo Orientação a Objetos com JavaScript

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.