javascript - nodejs - node js vs java español
¿Por qué llamar a una función en el REPL de Node.js con(funciona? (3)
Parece ser un error de REPL del nodo, poner estas dos líneas en un .js
causará un error de sintaxis.
function hi() { console.log("Hello, World!"); }
hi)(
Error:
SyntaxError: Unexpected token )
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
Emisión presentada #6634 .
Reproducido en v0.10.20.
v0.11.7 tiene esto arreglado.
$ nvm run 0.11.7
Running node v0.11.7
> function hi() { console.log("Hello, World!"); }
undefined
> hi)(
SyntaxError: Unexpected token )
at Object.exports.createScript (vm.js:44:10)
at REPLServer.defaultEval (repl.js:117:23)
at REPLServer.b [as eval] (domain.js:251:18)
at Interface.<anonymous> (repl.js:277:12)
at Interface.EventEmitter.emit (events.js:103:17)
at Interface._onLine (readline.js:194:10)
at Interface._line (readline.js:523:8)
at Interface._ttyWrite (readline.js:798:14)
at ReadStream.onkeypress (readline.js:98:10)
at ReadStream.EventEmitter.emit (events.js:106:17)
>
¿Por qué es posible llamar a la función en JavaScript como esta, probado con node.js:
~$ node
> function hi() { console.log("Hello, World!"); };
undefined
> hi
[Function: hi]
> hi()
Hello, World!
undefined
> hi)( // WTF?
Hello, World!
undefined
>
¿Por qué la última llamada, hi)(
, funciona? ¿Es un error en node.js, un error en el motor V8, un comportamiento oficialmente indefinido o un JavaScript realmente válido para todos los intérpretes?
Se debe a cómo el REPL evalúa la entrada, que es en última instancia como:
(hi)()
Los paréntesis adicionales se agregan para forzarlo a ser una expresión :
// First we attempt to eval as expression with parens.
// This catches ''{a : 1}'' properly.
self.eval(''('' + evalCmd + '')'',
// ...
La intención es tratar {...}
como Object
literales / initialisers lugar de como un block .
var stmt = ''{ "foo": "bar" }'';
var expr = ''('' + stmt + '')'';
console.log(eval(expr)); // Object {foo: "bar"}
console.log(eval(stmt)); // SyntaxError: Unexpected token :
Y, como leesei mencionó, esto se ha cambiado por 0.11.x, que simplemente ajustará { ... }
lugar de toda la entrada:
if (/^/s*/{/.test(evalCmd) && //}/s*$/.test(evalCmd)) {
// It''s confusing for `{ a : 1 }` to be interpreted as a block
// statement rather than an object literal. So, we first try
// to wrap it in parentheses, so that it will be interpreted as
// an expression.
evalCmd = ''('' + evalCmd + '')/n'';
} else {
// otherwise we just append a /n so that it will be either
// terminated, or continued onto the next expression if it''s an
// unexpected end of input.
evalCmd = evalCmd + ''/n'';
}
Se produjo un error hace 4 meses, para este problema https://github.com/joyent/node/issues/5698
Y el problema fue porque, REPL encierra las declaraciones con parens. Asi que
foo)(
se convierte en
(foo)()
La explicación real se puede encontrar aquí https://github.com/joyent/node/issues/5698#issuecomment-19487718 .