em JSON, por que cada nome está entre aspas?

91

A especificação JSON diz que JSON é um objeto ou uma matriz. No caso de um objeto,

Uma estrutura de objeto é representada como um par de chaves em torno de zero ou mais pares de nome / valor (ou membros). Um nome é uma string. ...

E mais tarde, a especificação diz que uma string está entre aspas.

Por quê?

Portanto,

{"Property1":"Value1","Property2":18}

e não

{Property1:"Value1",Property2:18}

Pergunta 1 : por que não permitir que o nome nos pares nome / valor sejam identificadores não citados?


Questão 2 : Existe diferença semântica entre as duas representações acima, quando avaliadas em Javascript?

Cheeso
fonte
1
@Bruno: Você poderia falar de XML da mesma maneira ... e, infelizmente, alguns por aí podem muito bem estar tentando usar XML como linguagem de programação ...
Mike DeSimone
2
+1 ... parece uma contradição peculiar ... "com aspas" torna-o JSON padrão, mas não funciona com eval()(isto é, javascript).
skaffman
2
@bruno, não. se você expandi-lo, ele se tornará "em Javascript Object Notation", o que é bom
Dave Archer
2
@skaffman - Funcionará quando avaliado em JavaScript.
Quentin de
1
@Bruno - JSON é um formato de dados. "Em JSON" significa - com dados formatados de acordo com as especificações.
Cheeso de

Respostas:

57

Pergunta 1: por que não permitir que o nome nos pares nome / valor sejam identificadores não citados?

A filosofia de design do JSON é "Keep it simple"

"Citar nomes com "" é muito mais simples do que "Você pode citar nomes com "ou 'mas não precisa, a menos que contenham certos caracteres (ou combinações de caracteres que tornariam uma palavra-chave) e / 'ou "talvez precisem ser citados, dependendo em qual delimitador você selecionou " .

Questão 2: Existe diferença semântica entre as duas representações acima, quando avaliadas em Javascript?

Não. Em JavaScript, eles são idênticos.

Quentin
fonte
3
Não, não está correto. CMS tem a resposta correta. Essa resposta é apenas um bom efeito colateral do verdadeiro motivo. Além de ser mais simples de explicar, também é mais simples escrever um analisador, já que você pode reutilizar as regras de análise para strings em identificadores.
Breton
Além disso, há uma ligeira diferença semântica no fato de que se um identificador for uma palavra reservada, ele será interpretado como essa palavra e não como um identificador.
Breton
2
+1 na resposta do CMS, isso é correto. As aspas duplas não são uma convenção de código, mas você deseja evitar as palavras reservadas como chaves no objeto. Por exemplo: {propriedade1: "abc", isto: "def"} é ERRADO (esta é uma palavra-chave reservada)
Sorin Mocanu
Pergunta 2 : Uma pequena diferença no Javascript ao usar a JSON.parsefunção: JSON.parse('{"a":1}') funciona bem , por que JSON.parse('{a:1}')gerará uma exceção .
nhnghia
@nhnghia - A pergunta 2 é sobre como avaliar o código-fonte como JavaScript , não JSON. JSON.parseé um analisador JSON implementado em JavaScript, não é um analisador JavaScript.
Quentin
134

Deixo uma citação de uma apresentação que Douglas Crockford (o criador do padrão JSON) fez ao Yahoo.

Ele fala sobre como descobriu o JSON e, entre outras coisas, por que decidiu usar as chaves citadas :

.... Foi quando descobrimos o problema do nome não mencionado. Acontece que o ECMA Script 3 tem uma política de palavras reservadas do tipo whack. As palavras reservadas devem ser citadas na posição chave, o que é realmente um incômodo. Quando comecei a formular isso em um padrão, não queria ter que colocar todas as palavras reservadas no padrão, porque pareceria muito estúpido.

Na época, eu estava tentando convencer as pessoas: sim, você pode escrever aplicativos em JavaScript, na verdade vai funcionar e é uma boa linguagem. Não quis dizer, então, ao mesmo tempo: e olhe só que bobagem eles fizeram! Então decidi, em vez disso, vamos apenas citar as chaves.
Assim, não precisamos contar a ninguém o quão maluco é.

É por isso que, até hoje, as chaves são citadas em JSON.

Você pode encontrar o vídeo completo e a transcrição aqui .

CMS
fonte
Ummm ... o criador do padrão JSON?! Eu acredito que isso é um exagero. JSON é o JavaScript Object Notation e vem da especificação Javascript (ECMA).
Sorin Mocanu
42
@Sorin: Não confunda JSON com literais de Objeto JavaScript. JSON é um formato de intercâmbio de dados independente de linguagem, proposto por Crockford em 2006 ( tools.ietf.org/html/rfc4627 ), sua gramática difere dos literais de objeto JavaScript ( bclary.com/2004/11/07/#a-11.1 .5 ), basicamente permitindo apenas chaves de string e os valores DEVEM ser um objeto , array , número , string ou um dos seguintes nomes literais: false , null true . Literais de objeto em JavaScript podem ter chaves como identificadores , literais de string ouLiterais numéricos , e o valor pode ser qualquer tipo de expressão ...
CMS
@CMS E o JavaScript de hoje permite identificadores abreviados dentro de expressões do construtor de objetos, por exemplo:, { a }onde a propriedade 'a' copia o valor de uma variável global ou local 'a'.
Hydroper
@CMS E também há chaves computadas:{[key]: value}
Hydroper
0

Ambos :e espaços em branco são permitidos em identificadores. Sem as aspas, isso causaria ambiguidade ao tentar determinar o que exatamente constitui o identificador.

Anon.
fonte
0

Em javascript, os objetos podem ser usados ​​como um hash / hashtable com pares de chaves.

No entanto, se sua chave tiver caracteres que o javascript não pode tokenizar como um nome, ela falhará ao tentar acessar como uma propriedade em um objeto em vez de uma chave.

var test  = {};
test["key"] = 1;
test["#my-div"] = "<div> stuff </div>";

// test = { "key": 1, "#my-div": "<div> stuff </div>" };

console.log(test.key);           // should be 1
console.log(test["key"]);        // should be 1
console.log(test["#my-div"]);    // should be "<div> stuff </div>";
console.log(test.#my-div);       // would not work.

identificadores às vezes podem ter caracteres que não podem ser avaliados como token / identificador em javascript, portanto, é melhor colocar todos os identificadores em strings para consistência.

michael herndon
fonte
-2

Acho que a resposta certa para a pergunta do Cheeso é que a implementação superou a documentação. Não requer mais uma string como chave, mas algo mais, que pode ser uma string (ou seja, entre aspas) ou (provavelmente) qualquer coisa que possa ser usada como um nome de variável, o que suponho que significa começar com uma letra _ , ou $, e inclui apenas letras, números e $ e _.

Eu queria simplificar o resto para a próxima pessoa que fizer essa pergunta com a mesma ideia que eu. Aqui está a carne:

Os nomes das variáveis ​​não são interpolados em JSON quando usados ​​como uma chave de objeto (Obrigado, Friedo!)

Breton, usando "identificador" em vez de "chave", escreveu que "se um identificador for uma palavra reservada, será interpretado como essa palavra e não como um identificador". Pode ser verdade, mas tentei sem problemas:

var a = {do:1,long:2,super:3,abstract:4,var:5,break:6,boolean:7};
a.break

=> 6

Sobre o uso de aspas, Quentin escreveu "... mas você não precisa, a menos que [a chave] contenha certos caracteres (ou combinações de caracteres que a tornariam uma palavra-chave)"

Descobri que a parte anterior (certos caracteres) é verdadeira, usando o sinal @ (na verdade, acho que $ e _ são os únicos caracteres que não causam o erro):

var a = {a@b:1};

=> Erro de sintaxe

var a = {"a@b":1};
a['a@b']

=> 1

mas o parênteses sobre palavras-chave, como mostrei acima, não é verdade.

O que eu queria funciona porque o texto entre a abertura {e os dois-pontos, ou entre a vírgula e os dois-pontos para as propriedades subsequentes é usado como uma string sem aspas para fazer uma chave de objeto ou, como Friedo colocou, um nome de variável não ' para ser interpolado:

var uid = getUID();
var token = getToken();            // Returns ABC123
var data = {uid:uid,token:token};
data.token

=> ABC123

Dave Scotese
fonte
-3

Se json descreve objetos, então, na prática, você obtém o seguinte

var foo = {};

var bar = 1;

foo["bar"] = "hello";
foo[bar] = "goodbye";

Então,

foo.bar == "hello";
foo[1] == "goodbye" // in setting it used the value of var bar

portanto, mesmo que seus exemplos produzam o mesmo resultado, seus equivalentes em "código bruto" não o farão. Talvez seja por isso ?? não sei, apenas uma ideia.

Dave Archer
fonte
3
@David, nomes de variáveis ​​não são interpolados em JS quando usados ​​como uma chave de objeto. { bar: 'goodbye' }não definirá o nome da chave com o valor de bar, será apenas bar. Os outros estão certos sobre o motivo pelo qual a especificação requer aspas: é para evitar conflitos de palavras-chave e caracteres especiais.
Friedo
-3

Pode reduzir o tamanho dos dados se aspas no nome forem permitidas apenas quando necessário

shashank joshi
fonte