Aprender uma linguagem de programação tem apenas dois aspectos: um é sintaxe e o outro é o tipo de dados. A sintaxe das linguagens do tipo C nada mais é do que se, enquanto, para funções, operações aritméticas, etc. e idiomas orientados a objetos são adicionados ao objeto.
A sintaxe é apenas um conjunto de regras que os designers de idiomas fizeram com antecedência. A gramática de diferentes idiomas é diferente, mas todos têm alguns pontos comuns. Para aqueles que estão familiarizados com uma ou duas linguagens de programação, a gramática geralmente não é um problema ao aprender outras linguagens de programação (é claro, se você está aprendendo idiomas do tipo C, definitivamente levará algum tempo para se envolver no LISP pela primeira vez). O foco da aprendizagem geralmente está nos tipos de dados e operações relacionadas, e não há ditado antigo: "Estrutura de dados + algoritmo = programa"! Em segundo lugar, a sintaxe de alguns idiomas tem problemas de design (o JavaScript é ainda mais), por isso não precisamos cavar esses pontos. Obviamente, se você afirma ser nerd, pode brincar com ele.
Este artigo fornecerá uma introdução detalhada aos tipos de dados em JavaScript.
Tipo fraco vs tipo forte
Dada a filosofia de design do JavaScript, o JavaScript é projetado como uma linguagem fraca.
Falando nisso, é inevitável falar sobre a diferença entre tipos fracos e tipos fortes.
Algumas pessoas pensam erroneamente que a diferença entre os dois é que "uma linguagem fortemente digitada precisa indicar seu tipo ao declarar uma variável, enquanto uma digitada fracamente não a usa". De fato, essa visão está errada. Por exemplo, o seguinte snippet de código Java:
A cópia do código é a seguinte:
String s = "hello";
int l = s.getBytes (). comprimento;
Como o compilador sabe que o comprimento é uma expressão legal? Isso ocorre porque o compilador sabe que o tipo de dados de S é string. Quando o método getBytes de string é chamado, o tipo de dados do valor de retorno é byte [], então .Length é uma expressão legal.
A verdadeira diferença entre os dois é:
Em idiomas fortemente digitados, o tipo de expressão pode ser determinado no tempo de compilação e apenas operações que se aplicam a esse tipo são permitidas;
Os idiomas de tipo fraco permitem que qualquer operação seja imposta a qualquer tipo, mas esta operação pode relatar um erro em tempo de execução.
Tipo de dados
De acordo com a especificação do ECMAScript 5.1, existem seis tipos de dados em JavaScript, a saber: indefinido, nulo, booleano, número, string e objeto. Os cinco primeiros pertencem a tipos básicos, e o último pertence a tipos de objetos.
Tipos de dados básicos
O tipo indefinido tem apenas um valor, que é indefinido, o que significa "valor nulo", que se aplica a todos os tipos de dados.
O tipo nulo tem apenas um valor, que é nulo, o que significa "nenhum objeto" e se aplica apenas aos tipos de objeto.
Tipo booleano tem dois valores, verdadeiros e falsos
Os valores do número de tipo são conjuntos de números de ponto flutuante de 64 bits que seguem o padrão IEEE 754, semelhante ao duplo de Java. Não há estrutura de dados inteira. Além disso, existem três valores especiais: nan, infinito, -infinity
Um valor da string do tipo é uma coleção de caracteres unicode finitos. Deve ser fechado com 'ou'.
nulo e indefinido
Tanto nulo quanto indefinido representam o conceito de "não valor", se for estritamente distinguido:
- nulo significa vazio
- indefinido significa que ele não existe. Este valor é todas as variáveis sem inicialização, falta de parâmetros na função e nenhum valor de retorno explícito.
Em outros idiomas, apenas um nulo é usado para representar valores nulos. Por que há um indefinido em JavaScript? Isso é causado por razões históricas:
O JavaScript adota a sintaxe java, divide tipos em tipos básicos e tipos de objetos. Em Java, Null é usado para representar objetos vazios, e JavaScript os herda como garantido; No idioma C, o NULL é 0 quando convertido em um número, e o JavaScript também adota o mesmo método:
A cópia do código é a seguinte:
> Número (nulo)
0
> 5 + nulo
5
No JavaScript 1.0, ainda não há manipulação de exceções. Para algumas exceções (sem variáveis inicializadas, parâmetros ausentes ao chamar funções, etc.), elas precisam ser marcadas como um valor especial. Null é uma boa escolha, mas Brendan Eich quer evitar as duas coisas a seguir:
- Este valor especial não deve ter um atributo de referência, porque é específico de objeto
- Este valor especial não deve ser convertido para 0, porque não é fácil detectar erros no programa
Por essas duas razões, Brendan Eich escolheu indefinido, o que pode ser forçado a Nan.
A cópia do código é a seguinte:
> Número (indefinido)
Nan
> 5 + indefinido
Nan
Os resultados são muito diferentes ao lidar com objetos JSON:
A cópia do código é a seguinte:
> Json.parse (nulo)
nulo
> Json.parse (indefinido)
// Firfox SyntaxError: json.parse: caractere inesperado na linha 1 da coluna 1 dos dados JSON
// Chrome SyntaxError: token inesperado u
> Json.stringify (nulo)
"nulo"
> Json.stringify (indefinido)
indefinido
Tipo de objeto
Como linguagem de script, o próprio JavaScript possui funções muito simplificadas e muitas funções (leitura e escrita de arquivos, redes etc.) são fornecidas pelo ambiente do host. A ponte entre o ambiente do host e a linguagem JavaScript é objetos. O ambiente do host fornece uma variedade de funções, fornecendo uma série de objetos que estão em conformidade com a sintaxe JavaScript.
Neste artigo, na programação orientada a objetos JavaScript (se você não sabe o que é um protótipo, recomendo fortemente ler este artigo), enfatizei repetidamente que os objetos são uma série de pares de valor-chave em JavaScript, assim como o hashmap em Java. No entanto, as propriedades dos objetos no JavaScript podem ter alguns descritores (descritores de propriedades), que não estão disponíveis no HashMap.
Descritor de atributo
Os descritores de atributos são divididos em duas categorias:
O descritor de dados (descritor de dados), contém uma série de valores booleanos, para indicar se o atributo permite modificação e exclusão.
Descritor de acessórios, incluindo funções Get e Set.
Ambos os descritores são objetos e ambos têm as duas propriedades booleanas a seguir:
Configurável é usado para especificar se o descritor permite modificação e exclusão. O padrão é falso.
Enumerable é usado para especificar se deve acessar a propriedade quando está atravessando um objeto (usando o método para ... no loop ou objeto.Keys). O padrão é falso.
Além dos dois atributos comuns acima, o descritor de dados tem os dois atributos a seguir:
- O valor é usado para especificar o valor desta propriedade, o padrão é indefinido
- A gravidade é usada para especificar se o valor da propriedade permite a alteração do valor da propriedade. O padrão é falso
Existem duas propriedades para os descritores de acesso:
- O GET é usado para especificar o acessador (getter, essencialmente uma função) ao acessar a propriedade, e o valor de retorno do acessador é o valor da propriedade. O padrão é indefinido
- O conjunto é usado para especificar o avaliador (setter, essencialmente uma função) ao acessar esta propriedade. O avaliador aceita um parâmetro. O padrão é indefinido
Podemos usar o Object.DefineProperty para definir o descritor da propriedade do objeto. Por exemplo:
A cópia do código é a seguinte:
// usando __proto__
Object.DefineProperty (obj, 'key', {
__proto__: nulo, // sem propriedades herdadas
Valor: 'estático' // não enumerável
// não configurável
// Não é gravável
// como padrões
});
A partir do exemplo acima, podemos ver que os descritores têm as características da herança. Definimos explicitamente o __proto__ do objeto descritor como NULL, que evita herdar os atributos correspondentes do object.prototype. Obviamente, também podemos definir explicitamente todas as propriedades do descritor:
A cópia do código é a seguinte:
// sendo explícito
Object.DefineProperty (obj, 'key', {
enumerável: falso,
Configurável: falso,
gravável: falso,
Valor: 'estático'
});
Este efeito é o mesmo que a primeira peça de código.
Aqui está outro exemplo de descritor de acesso:
A cópia do código é a seguinte:
// Exemplo de uma propriedade de objeto adicionada com DefineProperty com um descritor de propriedades de acessórios
var bValue = 38;
Object.DefineProperty (obj, 'key', {
get: function () {return bvalue; },
SET: function (newValue) {bvalue = newValue; },
enumerável: verdadeiro,
Configurável: Verdadeiro
});
Deve -se notar que descritores de acesso e descritores de dados não podem ser confundidos. É errado escrever o seguinte:
A cópia do código é a seguinte:
// Você não pode tentar misturar os dois:
Object.DefineProperty (OBJ, 'conflito', {
Valor: 0x9f91102,
get: function () {return 0xDeadBeef; }
});
// joga um tipo Eerror: os descritores da propriedade não devem especificar um valor
// ou seja gravável quando um getter ou setter foi especificado
typeof
Se você quiser saber o tipo de variável no tempo de execução, pode usar o operador TIPEOF. O valor de retorno do tipo OF é o seguinte:
Uma coisa que precisa ser observada é o tipo de null == "objeto". De acordo com o padrão ECMAScript 5.1, o tipo nulo deve ser um tipo básico. Por que o objeto é retornado aqui? O motivo é o seguinte:
No JavaScript 1.0, o valor no JavaScript é representado por uma estrutura como uma tag de tipo e um valor real. O sinalizador de tipo do objeto é 0 e o NULL representa um ponteiro nulo (0x00) na linguagem C; portanto, o sinalizador de tipo de nulo é 0.
O acima é o conteúdo inteiro deste artigo. Por favor, consulte, se precisar.