2015-10-01 04:40:46 +03:00
|
|
|
---
|
|
|
|
language: javascript
|
|
|
|
contributors:
|
|
|
|
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
|
|
|
|
- ["Ariel Krakowski", "http://www.learneroo.com"]
|
2015-10-04 22:13:11 +03:00
|
|
|
translators:
|
|
|
|
- ["Willian Justen", "http://willianjusten.com.br"]
|
|
|
|
lang: pt-br
|
2015-10-01 04:40:46 +03:00
|
|
|
---
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
JavaScript foi criada por Brendan Eich, funcionário da Netscape na época, em 1995. Ela
|
2015-10-01 04:40:46 +03:00
|
|
|
foi originalmente criada para ser uma linguagem de script para websites,
|
|
|
|
complementando o uso de Java para aplicações web mais complexas, mas a sua
|
|
|
|
integração com páginas web e seu suporte nativo nos browsers fez com que
|
|
|
|
ela se tornasse mais comum que Java no frontend web.
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
Javascript não é somente limitada a browsers web, existindo o Node.js,
|
2015-10-01 04:40:46 +03:00
|
|
|
que é um projeto que fornece um interpretador baseado no motor V8 do Google
|
|
|
|
Chrome e está se tornando cada vez mais famoso.
|
|
|
|
|
|
|
|
Feedback são muito apreciados! Você me encontrar em
|
|
|
|
[@adambrenecki](https://twitter.com/adambrenecki), ou
|
|
|
|
[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
|
|
|
|
|
|
|
|
```js
|
|
|
|
// Comentários são como em C. Comentários de uma linha começam com duas barras,
|
|
|
|
/* e comentários de múltplas linhas começam com barra-asterisco
|
|
|
|
e fecham com asterisco-barra */
|
|
|
|
|
|
|
|
// comandos podem ser terminados com ;
|
|
|
|
facaAlgo();
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// ... mas eles não precisam ser, o ponto-e-vírgula é automaticamente
|
2015-10-01 04:40:46 +03:00
|
|
|
// inserido quando há uma nova linha, exceto alguns casos.
|
|
|
|
facaAlgo()
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// Como esses casos podem causar resultados inesperados, vamos continuar
|
2015-10-01 04:40:46 +03:00
|
|
|
// a usar ponto-e-vírgula neste guia.
|
|
|
|
|
|
|
|
///////////////////////////////////
|
2015-10-02 04:23:18 +03:00
|
|
|
// 1. Números, Strings e Operadores
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Javascript tem um tipo de número (que é o 64-bit IEEE 754 double).
|
2015-10-04 22:13:11 +03:00
|
|
|
// Doubles tem uma mantissa 52-bit, que é suficiente para guardar inteiros
|
2015-10-02 04:23:18 +03:00
|
|
|
// acima de 9✕10¹⁵ precisamente.
|
2015-10-01 04:40:46 +03:00
|
|
|
3; // = 3
|
|
|
|
1.5; // = 1.5
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// A aritmética básica funciona como seria de se esperar.
|
2015-10-01 04:40:46 +03:00
|
|
|
1 + 1; // = 2
|
|
|
|
0.1 + 0.2; // = 0.30000000000000004
|
|
|
|
8 - 1; // = 7
|
|
|
|
10 * 2; // = 20
|
|
|
|
35 / 5; // = 7
|
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Inclusive divisão desigual.
|
2015-10-01 04:40:46 +03:00
|
|
|
5 / 2; // = 2.5
|
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Operadores Bitwise também funcionam; quando você faz uma operação bitwise
|
|
|
|
// seu float é convertido para um int de até 32 bits.
|
2015-10-01 04:40:46 +03:00
|
|
|
1 << 2; // = 4
|
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// A precedência é aplicada com parênteses.
|
2015-10-01 04:40:46 +03:00
|
|
|
(1 + 3) * 2; // = 8
|
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Existem três especiais valores não-é-número-real:
|
|
|
|
Infinity; // resultado de 1/0
|
|
|
|
-Infinity; // resultado de -1/0
|
|
|
|
NaN; // resultado de 0/0
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Existe também o tipo booleano.
|
2015-10-01 04:40:46 +03:00
|
|
|
true;
|
|
|
|
false;
|
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Strings são criados com ' ou ".
|
2015-10-01 04:40:46 +03:00
|
|
|
'abc';
|
2015-10-02 04:23:18 +03:00
|
|
|
"Olá, mundo";
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Negação usa o símbolo !
|
2015-10-01 04:40:46 +03:00
|
|
|
!true; // = false
|
|
|
|
!false; // = true
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// Igualdade é o sinal de ===
|
2015-10-01 04:40:46 +03:00
|
|
|
1 === 1; // = true
|
|
|
|
2 === 1; // = false
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// Desigualdade é o sinal de !==
|
2015-10-01 04:40:46 +03:00
|
|
|
1 !== 1; // = false
|
|
|
|
2 !== 1; // = true
|
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Mais comparações
|
2015-10-01 04:40:46 +03:00
|
|
|
1 < 10; // = true
|
|
|
|
1 > 10; // = false
|
|
|
|
2 <= 2; // = true
|
|
|
|
2 >= 2; // = true
|
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Strings são concatenadas com +
|
|
|
|
"Olá " + "mundo!"; // = "Olá mundo!"
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// e comparadas com < e >
|
2015-10-01 04:40:46 +03:00
|
|
|
"a" < "b"; // = true
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// A comparação de tipos não é feita com o uso de ==...
|
2015-10-01 04:40:46 +03:00
|
|
|
"5" == 5; // = true
|
|
|
|
null == undefined; // = true
|
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// ...a menos que use ===
|
2015-10-01 04:40:46 +03:00
|
|
|
"5" === 5; // = false
|
|
|
|
null === undefined; // = false
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// ...isso pode resultar em comportamentos estranhos...
|
2015-10-01 04:40:46 +03:00
|
|
|
13 + !0; // 14
|
|
|
|
"13" + !0; // '13true'
|
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Você pode acessar caracteres de uma String usando o `charAt`
|
|
|
|
"Isto é uma String".charAt(0); // = 'I'
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// ...ou usar `substring` para pegar pedaços maiores.
|
|
|
|
"Olá mundo".substring(0, 3); // = "Olá"
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// `length` é uma propriedade, portanto não use ().
|
|
|
|
"Olá".length; // = 3
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 04:23:18 +03:00
|
|
|
// Existe também o `null` e o `undefined`.
|
|
|
|
null; // usado para indicar um valor não considerado
|
|
|
|
undefined; // usado para indicar um valor que não é a atualmente definido
|
2015-10-04 22:13:11 +03:00
|
|
|
// (entretando `undefined` é considerado de fato um valor
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// false, null, undefined, NaN, 0 and "" são valores falsos;
|
|
|
|
// qualquer outro valor é verdadeiro
|
|
|
|
// Note que 0 é falso e "0" é verdadeiro, até mesmo 0 == "0".
|
2015-10-01 04:40:46 +03:00
|
|
|
|
|
|
|
///////////////////////////////////
|
2015-10-02 05:48:05 +03:00
|
|
|
// 2. Variáveis, Arrays e Objetos
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// Variáveis são declaradas com a palavra-chave `var`. O Javascript é
|
2015-10-02 05:48:05 +03:00
|
|
|
// dinâmicamente tipado, portanto você não precisa especificar o tipo.
|
|
|
|
// Atribuições usam um simples caracter de `=`.
|
2015-10-01 04:40:46 +03:00
|
|
|
var someVar = 5;
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// se você deixar de colocar a palavra-chave var, você não irá receber um erro...
|
2015-10-01 04:40:46 +03:00
|
|
|
someOtherVar = 10;
|
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// ...mas sua variável será criada no escopo global, não no escopo em que você
|
|
|
|
// definiu ela.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Variáveis declaradas sem receberem um valor são definidas como `undefined`.
|
2015-10-01 04:40:46 +03:00
|
|
|
var someThirdVar; // = undefined
|
|
|
|
|
2015-10-04 22:13:11 +03:00
|
|
|
// Existe um shorthand para operações matemáticas em variáveis:
|
2015-10-02 05:48:05 +03:00
|
|
|
someVar += 5; // equivalente a someVar = someVar + 5; someVar é 10 agora
|
|
|
|
someVar *= 10; // agora someVar é 100
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// e um para adição e subtração de 1
|
2015-10-04 22:13:11 +03:00
|
|
|
someVar++; // agora someVar é 101
|
|
|
|
someVar--; // volta para 100
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Arrays são listas ordenadas de valores, de qualquer tipo.
|
|
|
|
var myArray = ["Olá", 45, true];
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Seus membros podem ser acessados usando a sintaxe de colchetes.
|
|
|
|
// O indíce de um Array começa pelo 0.
|
2015-10-01 04:40:46 +03:00
|
|
|
myArray[1]; // = 45
|
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Arrays são mutáveis e de tamanho variável.
|
2015-10-01 04:40:46 +03:00
|
|
|
myArray.push("World");
|
|
|
|
myArray.length; // = 4
|
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Adicionar/modificar em um índice específico
|
2015-10-01 04:40:46 +03:00
|
|
|
myArray[3] = "Hello";
|
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Objetos de Javascript são equivalentes aos dicionários ou maps de outras
|
|
|
|
// linguagens: uma coleção não ordenada de pares chave-valor.
|
|
|
|
var myObj = {chave1: "Olá", chave2: "Mundo"};
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Chaves são strings, mas as aspas não são necessárias se elas são
|
|
|
|
// identificadores válidos no Javascript. Valores podem ser de qualquer tipo.
|
2015-10-01 04:40:46 +03:00
|
|
|
var myObj = {myKey: "myValue", "my other key": 4};
|
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Atributos de objetos também podem ser acessados com a sintaxe de colchetes.
|
2015-10-01 04:40:46 +03:00
|
|
|
myObj["my other key"]; // = 4
|
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// ... ou usando a sintaxe de ponto, passando a chave que é um identificador
|
|
|
|
// válido.
|
2015-10-01 04:40:46 +03:00
|
|
|
myObj.myKey; // = "myValue"
|
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Objetos são mutáveis, valores podem ser modificados e novas chaves
|
|
|
|
// adicionadas.
|
2015-10-01 04:40:46 +03:00
|
|
|
myObj.myThirdKey = true;
|
|
|
|
|
2015-10-02 05:48:05 +03:00
|
|
|
// Se você tentar acessar um valor que não foi determinado ainda, você irá
|
|
|
|
// receber `undefined`.
|
2015-10-01 04:40:46 +03:00
|
|
|
myObj.myFourthKey; // = undefined
|
|
|
|
|
|
|
|
///////////////////////////////////
|
2015-10-02 07:05:31 +03:00
|
|
|
// 3. Lógica e Estruturas de Controle
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 07:05:31 +03:00
|
|
|
// A sintaxe para essa seção é quase idêntica a maioria das linguagens.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
|
|
|
// The `if` structure works as you'd expect.
|
2015-10-02 07:05:31 +03:00
|
|
|
// A estrutura `if` funciona como deveria ser.
|
|
|
|
var count = 1
|
2015-10-01 04:40:46 +03:00
|
|
|
if (count == 3){
|
2015-10-02 07:05:31 +03:00
|
|
|
// executa se count é 3
|
2015-10-01 04:40:46 +03:00
|
|
|
} else if (count == 4){
|
2015-10-02 07:05:31 +03:00
|
|
|
// executa se count é 4
|
2015-10-01 04:40:46 +03:00
|
|
|
} else {
|
2015-10-02 07:05:31 +03:00
|
|
|
// executa se count não é 3 nem 4
|
2015-10-01 04:40:46 +03:00
|
|
|
}
|
|
|
|
|
2015-10-02 07:23:46 +03:00
|
|
|
// Como se faz um `while`.
|
2015-10-01 04:40:46 +03:00
|
|
|
while (true){
|
2015-10-02 07:05:31 +03:00
|
|
|
// Um loop infinito!
|
2015-10-01 04:40:46 +03:00
|
|
|
}
|
|
|
|
|
2015-10-02 07:05:31 +03:00
|
|
|
// Os loops do-while são como os loops de while, exceto quando eles sempre
|
|
|
|
// executam pelo menos uma vez.
|
2015-10-01 04:40:46 +03:00
|
|
|
do {
|
|
|
|
input = getInput();
|
|
|
|
} while (!isValid(input))
|
|
|
|
|
|
|
|
// The `for` loop is the same as C and Java:
|
|
|
|
// initialisation; continue condition; iteration.
|
2015-10-02 07:05:31 +03:00
|
|
|
|
|
|
|
// O loop `for` é o mesmo de C e Java:
|
2015-10-02 07:23:46 +03:00
|
|
|
// inicialização, condição para continuar; iteração
|
2015-10-01 04:40:46 +03:00
|
|
|
for (var i = 0; i < 5; i++){
|
2015-10-02 07:05:31 +03:00
|
|
|
// vai rodar cinco vezes
|
2015-10-01 04:40:46 +03:00
|
|
|
}
|
|
|
|
|
2015-10-02 07:05:31 +03:00
|
|
|
// && é o `e` lógico , || é o `ou` lógico
|
2015-10-01 04:40:46 +03:00
|
|
|
if (house.size == "big" && house.colour == "blue"){
|
|
|
|
house.contains = "bear";
|
|
|
|
}
|
2015-10-02 07:05:31 +03:00
|
|
|
if (cor == "red" || cor == "blue"){
|
|
|
|
// cor é vermelha OU azul
|
2015-10-01 04:40:46 +03:00
|
|
|
}
|
|
|
|
|
2015-10-02 07:05:31 +03:00
|
|
|
// && e || "pequeno circuito", é útil para determinar valores padrões.
|
|
|
|
var name = otherName || "padrão";
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 07:05:31 +03:00
|
|
|
// O `switch` checa pela igualdade com `===`.
|
|
|
|
// Use `break` após cada `case`
|
2015-10-01 04:40:46 +03:00
|
|
|
grade = 'B';
|
|
|
|
switch (grade) {
|
|
|
|
case 'A':
|
|
|
|
console.log("Great job");
|
|
|
|
break;
|
|
|
|
case 'B':
|
|
|
|
console.log("OK job");
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
console.log("You can do better");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.log("Oy vey");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////
|
2015-10-02 07:23:46 +03:00
|
|
|
// 4. Funções, Escopos e Closures
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 07:23:46 +03:00
|
|
|
// Funções Javascript são declaradas com a palavra-chave `function`.
|
2015-10-01 04:40:46 +03:00
|
|
|
function myFunction(thing){
|
|
|
|
return thing.toUpperCase();
|
|
|
|
}
|
|
|
|
myFunction("foo"); // = "FOO"
|
|
|
|
|
2015-10-02 07:23:46 +03:00
|
|
|
// Repare que o valor a ser retornado deve começar na mesma linha que
|
|
|
|
// a palavra-chave `return`, senão você sempre irá retornar `undefined`
|
|
|
|
// visto que o ponto-e-vírgula é inserido automáticamente nas quebras de
|
|
|
|
// linha. Preste atenção quando usar o estilo Allman.
|
2015-10-01 04:40:46 +03:00
|
|
|
function myFunction()
|
|
|
|
{
|
2015-10-02 07:23:46 +03:00
|
|
|
return // <- ponto-e-vírgula adicionado automaticamente aqui
|
2015-10-01 04:40:46 +03:00
|
|
|
{
|
|
|
|
thisIsAn: 'object literal'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
myFunction(); // = undefined
|
|
|
|
|
2015-10-02 07:23:46 +03:00
|
|
|
// Funções Javascript são objetos de primeira classe, portanto elas podem
|
|
|
|
// ser atribuídas a nomes de variáveis e serem passadas para outras funções
|
|
|
|
// como argumentos - por exemplo, quando criamos um manipulador de eventos:
|
2015-10-01 04:40:46 +03:00
|
|
|
function myFunction(){
|
2015-10-02 07:23:46 +03:00
|
|
|
// este código será chamado em 5 segundos
|
2015-10-01 04:40:46 +03:00
|
|
|
}
|
|
|
|
setTimeout(myFunction, 5000);
|
2015-10-02 07:23:46 +03:00
|
|
|
// Nota: `setTimeout` não é parte da linguagem Javascript, mas é provido pelos
|
|
|
|
// browsers e o Node.js.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 07:23:46 +03:00
|
|
|
// Objetos de funções não precisam nem serem declarados com nome - você pode
|
|
|
|
// escrever a definição de uma função anônima diretamente nos argumentos de
|
|
|
|
// outra função.
|
2015-10-01 04:40:46 +03:00
|
|
|
setTimeout(function(){
|
2015-10-02 07:23:46 +03:00
|
|
|
// este código será chamado em 5 segundos
|
2015-10-01 04:40:46 +03:00
|
|
|
}, 5000);
|
|
|
|
|
2015-10-02 07:23:46 +03:00
|
|
|
// O Javascript tem escopo de função; as funções tem seu próprio escopo,
|
|
|
|
// mas outros blocos não.
|
2015-10-01 04:40:46 +03:00
|
|
|
if (true){
|
|
|
|
var i = 5;
|
|
|
|
}
|
2015-10-02 07:23:46 +03:00
|
|
|
i; // = 5 - não `undefined` como você esperaria numa linguagem de blogo-escopo
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-02 07:23:46 +03:00
|
|
|
// Isso levou a padrão comum chamado de IIFE (Imediately Invoked Function
|
|
|
|
// Expression) ou (Expressão de Função Invocada Imediatamente), que previne
|
|
|
|
// que variáveis temporárias vazem para o escopo global.
|
2015-10-01 04:40:46 +03:00
|
|
|
(function(){
|
|
|
|
var temporary = 5;
|
2015-10-02 07:23:46 +03:00
|
|
|
// Nós podemos acessar o escopo global definindo o "objeto global", que
|
|
|
|
// no browser vai ser sempre `window`. O objeto global pode ter um nome
|
|
|
|
// diferente para ambiente não-browser como o Node.js.
|
2015-10-01 04:40:46 +03:00
|
|
|
window.permanent = 10;
|
|
|
|
})();
|
2015-10-02 07:23:46 +03:00
|
|
|
temporary; // levanta um erro de referência inexiste
|
2015-10-01 04:40:46 +03:00
|
|
|
permanent; // = 10
|
|
|
|
|
2015-10-02 07:23:46 +03:00
|
|
|
// Uma das principais características do Javascript é a closure. Que é
|
|
|
|
// uma função definida dentro de outra função, a função interna pode acessar
|
|
|
|
// todas as variáveis da função externa, mesmo depois da função de fora
|
|
|
|
// finalizar sua execução.
|
2015-10-01 04:40:46 +03:00
|
|
|
function sayHelloInFiveSeconds(name){
|
|
|
|
var prompt = "Hello, " + name + "!";
|
2015-10-02 07:23:46 +03:00
|
|
|
|
|
|
|
// Funções internas são colocadas no escopo local por padrão, assim como
|
|
|
|
// se fossem declaradas com `var`.
|
2015-10-01 04:40:46 +03:00
|
|
|
function inner(){
|
|
|
|
alert(prompt);
|
|
|
|
}
|
|
|
|
setTimeout(inner, 5000);
|
2015-10-02 07:23:46 +03:00
|
|
|
// `setTimeout` é assíncrono, portanto a função `sayHelloInFiveSeconds`
|
|
|
|
// vai sair imediatamente, e o `setTimeout` irá chamar a interna depois.
|
|
|
|
// Entretanto. como a interna é fechada dentro de "sayHelloInFiveSeconds",
|
|
|
|
// a interna permanece podendo acessar a variável `prompt` quando depois
|
|
|
|
// de chamada.
|
2015-10-01 04:40:46 +03:00
|
|
|
}
|
2015-10-02 07:23:46 +03:00
|
|
|
sayHelloInFiveSeconds("Adam"); // Vai abrir um popup com "Hello, Adam!" em 5s
|
2015-10-01 04:40:46 +03:00
|
|
|
|
|
|
|
///////////////////////////////////
|
2015-10-03 19:49:07 +03:00
|
|
|
// 5. Mais sobre Objetos; Construtores e Prototypes
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Objetos podem conter funções.
|
2015-10-01 04:40:46 +03:00
|
|
|
var myObj = {
|
|
|
|
myFunc: function(){
|
2015-10-03 19:49:07 +03:00
|
|
|
return "Olá mundo!";
|
2015-10-01 04:40:46 +03:00
|
|
|
}
|
|
|
|
};
|
2015-10-03 19:49:07 +03:00
|
|
|
myObj.myFunc(); // = "Olá mundo!"
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Quando uma função ligada a um objeto é chamada, ela pode acessar o objeto
|
|
|
|
// da qual foi ligada usando a palavra-chave `this`.
|
2015-10-01 04:40:46 +03:00
|
|
|
myObj = {
|
2015-10-03 19:49:07 +03:00
|
|
|
myString: "Olá mundo!",
|
2015-10-01 04:40:46 +03:00
|
|
|
myFunc: function(){
|
|
|
|
return this.myString;
|
|
|
|
}
|
|
|
|
};
|
2015-10-03 19:49:07 +03:00
|
|
|
myObj.myFunc(); // = "Olá mundo!"
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// O `this` só funciona para dentro do escopo do objeto, portanto, se chamarmos
|
|
|
|
// um método do objeto fora de seu escopo, este não irá funcionar.
|
2015-10-01 04:40:46 +03:00
|
|
|
var myFunc = myObj.myFunc;
|
|
|
|
myFunc(); // = undefined
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Inversamente, uma função pode ser atribuída a um objeto e ganhar a acesso
|
|
|
|
// através do `this`, até mesmo se ela não for chamada quando foi definida.
|
2015-10-01 04:40:46 +03:00
|
|
|
var myOtherFunc = function(){
|
|
|
|
return this.myString.toUpperCase();
|
|
|
|
}
|
|
|
|
myObj.myOtherFunc = myOtherFunc;
|
2015-10-03 19:49:07 +03:00
|
|
|
myObj.myOtherFunc(); // = "OLÁ MUNDO!"
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Nós podemos também especificar um contexto onde a função irá executar,
|
|
|
|
// usando o `call` ou `apply`.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
|
|
|
var anotherFunc = function(s){
|
|
|
|
return this.myString + s;
|
|
|
|
}
|
2015-10-03 19:49:07 +03:00
|
|
|
anotherFunc.call(myObj, " E Olá Lua!"); // = "Olá mundo! E Olá Lua!"
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// A função `apply` é praticamente a mesma coisa, mas ela pega um array
|
|
|
|
// como lista de argumentos.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
anotherFunc.apply(myObj, [" E Olá Sol!"]); // = "Olá mundo! E Olá Sol!"
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Isto é util quando trabalhamos com uma função que aceita uma sequência de
|
|
|
|
// argumentos e você quer passar um array.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
|
|
|
Math.min(42, 6, 27); // = 6
|
|
|
|
Math.min([42, 6, 27]); // = NaN (uh-oh!)
|
|
|
|
Math.min.apply(Math, [42, 6, 27]); // = 6
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Mas, o `call` e `apply` são somente temporários. Quando você quiser que
|
|
|
|
// permaneça sempre no escopo, use `bind`.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
|
|
|
var boundFunc = anotherFunc.bind(myObj);
|
2015-10-03 19:49:07 +03:00
|
|
|
boundFunc(" E Olá Saturno!"); // = "Olá mundo! E Olá Saturno!"
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// `bind` também pode ser usado para parcialmente aplicar (curry) uma função.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
|
|
|
var product = function(a, b){ return a * b; }
|
|
|
|
var doubler = product.bind(this, 2);
|
|
|
|
doubler(8); // = 16
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Quando você invoca uma função com a palavra-chave `new`, um novo objeto
|
|
|
|
// é criado, e fica disponível para a função pela palavra-chave `this`.
|
|
|
|
// Funções são desenhadas para serem invocadas como se invocam os construtores.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
|
|
|
var MyConstructor = function(){
|
|
|
|
this.myNumber = 5;
|
|
|
|
}
|
|
|
|
myNewObj = new MyConstructor(); // = {myNumber: 5}
|
|
|
|
myNewObj.myNumber; // = 5
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Todo objeto JavaScript possui um `prototype`. Quando você tenta acessar
|
|
|
|
// uma propriedade de um objeto que não existe no objeto atual, o interpretador
|
|
|
|
// vai olhar imediatamente para o seu prototype.
|
|
|
|
|
|
|
|
// Algumas implementações em JS deixam você acessar o objeto prototype com a
|
|
|
|
// propriedade mágica `__proto__`. Enquanto isso é util para explicar
|
|
|
|
// prototypes, não é parte de um padrão; nós vamos falar de algumas formas de
|
|
|
|
// usar prototypes depois.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
|
|
|
var myObj = {
|
2015-10-03 19:49:07 +03:00
|
|
|
myString: "Olá Mundo!"
|
2015-10-01 04:40:46 +03:00
|
|
|
};
|
|
|
|
var myPrototype = {
|
|
|
|
meaningOfLife: 42,
|
|
|
|
myFunc: function(){
|
|
|
|
return this.myString.toLowerCase()
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
myObj.__proto__ = myPrototype;
|
|
|
|
myObj.meaningOfLife; // = 42
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Isto funciona para funções, também.
|
|
|
|
myObj.myFunc(); // = "olá mundo!"
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// É claro, se sua propriedade não está em seu prototype,
|
|
|
|
// o prototype do prototype será procurado e por aí vai.
|
2015-10-01 04:40:46 +03:00
|
|
|
myPrototype.__proto__ = {
|
|
|
|
myBoolean: true
|
|
|
|
};
|
|
|
|
myObj.myBoolean; // = true
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Não há cópia envolvida aqui; cada objeto guarda uma referência do
|
|
|
|
// prototype. Isso significa que podemos alterar o prototype e nossas mudanças
|
|
|
|
// serão refletidas em qualquer lugar.
|
2015-10-01 04:40:46 +03:00
|
|
|
myPrototype.meaningOfLife = 43;
|
|
|
|
myObj.meaningOfLife; // = 43
|
|
|
|
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Nós mencionamos que o `__proto__` não é uma forma padrão, e não há uma
|
|
|
|
// forma padrão de mudar o prototype de um objeto já existente. Entretanto,
|
|
|
|
// existem duas formas de se criar um objeto com um dado prototype.
|
|
|
|
|
|
|
|
// A primeira forma é `Object.create`, que é uma adição recente do JS,
|
|
|
|
// e ainda não está disponível em todas as implementações.
|
2015-10-01 04:40:46 +03:00
|
|
|
var myObj = Object.create(myPrototype);
|
|
|
|
myObj.meaningOfLife; // = 43
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// A segunda forma, que funciona em qualquer lugar, é feita com construtores.
|
|
|
|
// Construtores tem uma propriedade chamada prototype. Este *não* é o prototype
|
|
|
|
// do construtor em si; ao invés disso, ele é o prototype dos novos objetos
|
|
|
|
// criados pelo construtor.
|
2015-10-01 04:40:46 +03:00
|
|
|
MyConstructor.prototype = {
|
|
|
|
myNumber: 5,
|
|
|
|
getMyNumber: function(){
|
|
|
|
return this.myNumber;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var myNewObj2 = new MyConstructor();
|
|
|
|
myNewObj2.getMyNumber(); // = 5
|
|
|
|
myNewObj2.myNumber = 6
|
|
|
|
myNewObj2.getMyNumber(); // = 6
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Tipos originais da linguagem como strings e números também possuem
|
|
|
|
// construtores equivalentes.
|
2015-10-01 04:40:46 +03:00
|
|
|
var myNumber = 12;
|
|
|
|
var myNumberObj = new Number(12);
|
|
|
|
myNumber == myNumberObj; // = true
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Exceto, que eles não são totalmente equivalentes.
|
2015-10-01 04:40:46 +03:00
|
|
|
typeof myNumber; // = 'number'
|
|
|
|
typeof myNumberObj; // = 'object'
|
|
|
|
myNumber === myNumberObj; // = false
|
|
|
|
if (0){
|
2015-10-03 19:49:07 +03:00
|
|
|
// O código não vai executar, porque 0 é um valor falso.
|
2015-10-01 04:40:46 +03:00
|
|
|
}
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Entretanto, esses objetos encapsulados e as funções originais compartilham
|
|
|
|
// um mesmo prototype, portanto você pode adicionar funcionalidades a uma string,
|
|
|
|
// por exemplo.
|
2015-10-01 04:40:46 +03:00
|
|
|
String.prototype.firstCharacter = function(){
|
|
|
|
return this.charAt(0);
|
|
|
|
}
|
|
|
|
"abc".firstCharacter(); // = "a"
|
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Esse fato é usado para criar os chamados `polyfills`, que implementam
|
|
|
|
// uma nova característica do Javascript em uma versão mais velha, para que
|
|
|
|
// assim funcionem em ambientes mais velhos como browsers ultrapassados.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 19:49:07 +03:00
|
|
|
// Havíamos mencionado que `Object.create` não estava ainda disponível em
|
|
|
|
// todos as implementações, mas nós podemos usá-lo com esse polyfill:
|
2015-10-31 21:31:22 +03:00
|
|
|
if (Object.create === undefined){ // Não o sobrescreve se já existir
|
2015-10-01 04:40:46 +03:00
|
|
|
Object.create = function(proto){
|
2015-10-03 19:49:07 +03:00
|
|
|
// faz um construtor temporário com o prototype certo
|
2015-10-01 04:40:46 +03:00
|
|
|
var Constructor = function(){};
|
|
|
|
Constructor.prototype = proto;
|
2015-10-03 19:49:07 +03:00
|
|
|
// então utiliza o new para criar um objeto prototype apropriado
|
2015-10-01 04:40:46 +03:00
|
|
|
return new Constructor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2015-10-03 20:03:54 +03:00
|
|
|
## Leitura Adicional
|
|
|
|
|
|
|
|
O [Mozilla Developer
|
2016-01-20 01:54:37 +03:00
|
|
|
Network](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript) dispõe de uma
|
2015-10-03 20:03:54 +03:00
|
|
|
excelente documentação sobre Javascript e seu uso nos browsers. E mais,
|
|
|
|
é uma wiki, portanto conforme você vai aprendendo, mais você pode ir ajudando
|
|
|
|
os outros compartilhando do seu conhecimento.
|
|
|
|
|
|
|
|
[Uma re-introdução do JavaScript pela MDN]
|
2016-01-20 01:54:37 +03:00
|
|
|
(https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
2015-10-03 20:03:54 +03:00
|
|
|
cobre muito dos conceitos abordados aqui em mais detalhes. Este guia fala
|
|
|
|
somente sobre a linguagem JavaScript em si; se você quiser aprender mais
|
|
|
|
sobre e como usar o JavaScript em páginas na web, comece aprendendo sobre
|
2015-10-01 04:40:46 +03:00
|
|
|
[Document Object
|
|
|
|
Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
|
|
|
|
|
2015-10-03 20:03:54 +03:00
|
|
|
[Aprenda Javascript por Exemplos e com Desafios](http://www.learneroo.com/modules/64/nodes/350) é uma
|
|
|
|
variação desse guia com desafios.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 20:03:54 +03:00
|
|
|
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) é um guia
|
|
|
|
profundo de todas as partes do JavaScript.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 20:03:54 +03:00
|
|
|
[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) é o guia clássico
|
|
|
|
/ livro de referência.
|
2015-10-01 04:40:46 +03:00
|
|
|
|
2015-10-03 20:03:54 +03:00
|
|
|
Parte desse artigo foi adaptado do tutorial de Python do Louie Dinh que está
|
2016-01-20 01:54:37 +03:00
|
|
|
nesse site e do [Tutorial de JS](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
2015-10-03 20:03:54 +03:00
|
|
|
da Mozilla Developer Network.
|