同名的变量和函数在块内返回错误



如果我们声明一个变量和一个同名的函数,它接受重新声明。但是当我们在块内做同样的事情时,它会显示重新声明错误
法典:

var x;
function x() {}; // no error.

但在这种情况下,我遇到了错误。

{
var inside; // re-declaration error.
function inside() {};
}

预期结果应没有错误。

这是EcmaScript 6 的一个更改。从 ES6 开始,不再允许在块范围内具有重复绑定。

ES5 规范没有这样的限制,但在 ES6 规范中,语义已更改:

13.2.1 静态语义:早期错误

: {语句列表}

  • 如果StatementList的 LexallyDeclaredNames 包含任何重复的条目,则这是一个语法错误。

  • 如果 LexallyDeclaredNames of StatementList 的任何元素也出现在 VarDeclaredNames ofStatementList中,则为语法错误。

第一部分是相关的 -LexicallyDeclaredNames包含在块内代码中找到的所有声明。

据推测,这是 ES6 中语义函数声明更改的一部分,因为现在它们可以被块作用域:

{ //block 1
function foo() { // declared in block 1
return 1;
}
console.log("block 1: foo() === 1", foo() === 1);

{ // block 2
function foo() { // declared in block 2
return 2;
}
console.log("block 2: foo() === 2", foo() === 2);
}

console.log("block 1: foo() === 1", foo() === 1);
}

这是这个等效的 ES5 代码上的语法糖:

(function() { //block 1
var foo = function() {
return 1;
}
console.log("block 1: foo() === 1", foo() === 1);
(function() { //block 2
var foo = function() {
return 2;
}
console.log("block 2: foo() === 2", foo() === 2);
})();
console.log("block 1: foo() === 1", foo() === 1);
})();

但是,此功能不能使用重复的名称。

对于任何块,包括其他类型的块语句,都存在相同的行为。下面是一个示例:

{ //block
function foo() { return 1; }
console.log("block: foo() === 1", foo() === 1);

if (true) { // if block
function foo() { return 2; }
console.log("if block: foo() === 2", foo() === 2);
}

for (var i = 0; i < 1; i++) { // for block
function foo() { return 3; }
console.log("for block: foo() === 3", foo() === 3);
}

switch ("hello world") { // case block
default:
function foo() { return 4; }
console.log("case block: foo() === 4", foo() === 4);
}

console.log("block: foo() === 1", foo() === 1);
}

但是,应该注意的是,相同类型(varfunction)的重复声明不会导致错误:

{
var foo = 1;
var foo = 2;

console.log("foo ->", foo);
}
{
function bar() { return "a"; }
function bar() { return "b"; }

console.log("bar() ->", bar());
}

因此,似乎它们没有被视为不同的声明,而是覆盖相同的词法声明名称。

在进一步探索时,我遇到了这个: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError

有趣的是,在这种情况下,我的结果与他们的结果不同:

try{
eval(`{
var x;
function x(){};
}`);
}catch(e){
console.log(e instanceof SyntaxError);
console.log(e.message);                // "Hello"
console.log(e.name);                   // "SyntaxError"
console.log(e.fileName);               // "someFile.js"
console.log(e.lineNumber);             // 10
console.log(e.columnNumber);           // 0
console.log(e.stack);                  // "@Scratchpad/2:11:9n"
}

结果:

true // instanceof SyntaxError
06:01:10.526 VM3194:22 Identifier 'x' has already been declared // e.message
06:01:10.527 VM3194:23 SyntaxError // e.name
06:01:10.527 VM3194:24 undefined   // e.filename
06:01:10.527 VM3194:25 undefined   // e.lineNumber
06:01:10.527 VM3194:26 undefined   // e.columnNumber
06:01:10.527 VM3194:27 SyntaxError: Identifier 'x' has already been declared at VM3194:16 // e.stack

相关内容

  • 没有找到相关文章

最新更新