2017-09-22 2 views
0

Comme indiqué ci-dessous, cas 1, cas 2 et cas 3 access a property d'un objet contenant computed property name.L'accesseur de propriété JS sur le nom de propriété calculé se comporte différemment dans l'expression et l'affectation

Le cas 1 crée un tel objet dans un argument de fonction, alors que le cas 2 crée un tel objet dans une affectation. Le cas 3 crée un tel objet dans une déclaration.

Pourquoi le cas 3 génère-t-il une erreur de syntaxe?

Case 1

$ node -e "var other = 'b'; console.log({a: 1, [other]: 2}[other]);" 
2 

Case 2

$ node -e "var other = 'b'; var obj = {a: 1, [other]: 2}[other]; console.log(obj);" 
2 

Case 3

$ node -e "var other = 'b'; {a: 1, [other]: 2}[other];" 
[eval]:1 
var other = 'b'; {a: 1, [other]: 2}[other]; 
          ^

SyntaxError: Unexpected token : 
    at createScript (vm.js:56:10) 
    at Object.runInThisContext (vm.js:97:10) 
    at Object.<anonymous> ([eval]-wrapper:6:22) 
    at Module._compile (module.js:570:32) 
    at evalScript (bootstrap_node.js:353:27) 
    at run (bootstrap_node.js:122:11) 
    at run (bootstrap_node.js:389:7) 
    at startup (bootstrap_node.js:121:9) 
    at bootstrap_node.js:504:3 

Version Noeuds

$ node --version 
v6.11.2 

Répondre

3

En bref, vous prenez les accolades comme block statement, pas comme object.

L'erreur provient d'un label, qui ne peut pas être un computed property name, car il doit être une indentifier, et non une propriété calculée.

Le premier appel est défini comme une expression, ce qui n'est pas le cas dans le dernier cas.

Pour éviter cela, vous pouvez envelopper les accolades entre parenthèses pour une expression.

eval("var other = 'b'; {a: 1, console.log('block!') };"); 
 
console.log(eval("var other = 'b'; ({a: 1, [other]: 2})[other];"));

+0

Bonne prise! Qu'est-ce qu'un label? Je ne l'ai jamais utilisé (je ne l'utiliserai probablement jamais). – ftor

+0

@ftor, vous pouvez suivre le lien. une utilisation pratique est de casser la boucle externe 'for' avec des boucles imbriquées. –