我被问到一个问题
{
function foo() {
console.log('A');
}
foo();
foo = 1;
function foo() {
console.log('B');
}
foo = 2;
console.log(foo);
}
console.log(foo);Run Code Online (Sandbox Code Playgroud)
为什么第三个输出是1而不是2?
不应该foo创建块作用域,因为该块中既没有let也没有const。但是第二个foo输出2意味着确实foo已经创建了另一个引用。
到底是怎么回事?
PS 我正在使用 Chrome
Version 89.0.4389.90 (Official Build) (x86_64)。
据我了解,IIFE模式是一个解决ES5及以下无法创建块范围的事实.通过将所有内容包装在函数中并立即调用它,我们可以创建一个范围.
现在,let并且const将获得更多浏览器的支持,这是否减少了对IIFE模式之类的需求?
以下几行JavaScript
try {
function _free() {}
var _free = 1;
} finally { }
Run Code Online (Sandbox Code Playgroud)
导致以下错误:
Uncaught SyntaxError: Identifier '_free' has already been declared
Run Code Online (Sandbox Code Playgroud)
但是,以下两个JavaScript代码块不会:
没有try块范围:
function _free() {}
var _free = 1;
Run Code Online (Sandbox Code Playgroud)在function范围内:
function a() {
function _free() {}
var _free = 1;
}
Run Code Online (Sandbox Code Playgroud)但为什么?
(测试环境:Chromium 61.0.3126.0)
var a = 0;
if (true) {
console.log(a)
a = 1;
function a() {}
a = 21
console.log(a)
}
console.log(a)Run Code Online (Sandbox Code Playgroud)
在我看来,因为函数声明提升,a = 1以及 a = 21会改变局部函数变量,所以在块中会输出21,外面是0,但真正的结果是在输出1之外。
用chrome调试,结果是这样
当运行时function a() {},它会改变局部和全局变量。太奇怪了?谁能给我解释一下?
ECMAScript 6中的块作用域功能是什么?
任何人都可以帮助我理解块区域功能与ECMAScript 5相比的主要区别吗?
var a;
if (true) {
a = 5;
function a() {}
a = 0;
console.log(a)
}
console.log(a)Run Code Online (Sandbox Code Playgroud)
我看到了上面的代码,在{}中声明了一个函数。我认为它会打印0 0,但它会打印0 5
我是JS的新手"strict mode";,当我使用代码时:
function outer(){
"use strict";
var ctype;
function inner(){
if(ctype!=undefined){
function hello1(){
console.log("hello1");
}
hello1()
}else {
function hello2(){
console.log("hello2");
}
hello2();
}
}
return inner;
}
var inner = outer();
inner();
Run Code Online (Sandbox Code Playgroud)
我想知道为什么Chrome(第49版)没有给出任何错误,但是Node.js可以给出" SyntaxError:在严格模式代码中,函数只能在顶级或者在另一个函数中声明. "
此表指出我的Chrome应报告错误.
"use strict";
if (true) {
function foo() {
}
}
Run Code Online (Sandbox Code Playgroud)
在PhpStorm中,此代码显示错误:
禁止在程序或功能的顶级功能声明
但是,Chrome很乐意执行它,即使在调试器中也没有任何控制台输出.
现在禁止或不禁止?
console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10
Run Code Online (Sandbox Code Playgroud)
====================
var a = 1;
if(true){
function a(){};
var a = 10;
}
console.log(a) // this code throws Uncaught SyntaxError: Identifier 'a' has already been declared
Run Code Online (Sandbox Code Playgroud)
除了if块之外,上面两个代码片段是相同的.为什么后者在javascript中允许delcare同一个变量两次在同一范围内使用var,如下所示抛出错误
function a(){};
var a = 10; //no error
Run Code Online (Sandbox Code Playgroud)
同样对于在上面的代码中从var变量= 10中删除var之后略有不同的情况,那么它工作正常但输出却令人惊讶
var a = 1;
if(true) {
function a(){};
a = 10;
}
console.log(a) //output:ƒ a(){}
Run Code Online (Sandbox Code Playgroud)
我很惊讶地看到这个输出,因为我期待10 ..因为在if块内声明的两个变量引用上面声明的相同变量javascript var不尊重块范围但功能范围...所以为什么不输出上面应该10点?当用函数表达式替换函数定义时,下面的代码输出10,就像我预期的那样.
var a = 1;
if(true) {
var a = function(){ …Run Code Online (Sandbox Code Playgroud) 下面的代码应该工作吗?
if(true) {
async function bar() {
console.log("hello");
}
}
bar();
Run Code Online (Sandbox Code Playgroud)
Chrome 80 和 Firefox 72 都抛出了未定义的ReferenceError说法bar。所以看起来async function bar() {...}声明是块范围的,而function bar() {...}声明是函数范围的?如果是这种情况,我会感到困惑,但是有人可以通过指向规范相关部分的链接为我确认这一点吗?
另外,有没有办法async function在块内声明时声明函数范围?
javascript ×10
hoisting ×3
scope ×3
ecmascript-6 ×2
async-await ×1
node.js ×1
strict ×1
syntax-error ×1
var ×1