javascript - JavaScript函数声明作用域是 block 还是函数?

标签 javascript function scope

<分区>

MDN 说“函数声明的范围也限制在声明发生的 block 内”(link)并显示了一个示例:

foo('outside');  // TypeError: foo is not a function
{
  function foo(location) {
   console.log('foo is called ' + location);
  }
  foo('inside'); // works correctly and logs 'foo is called inside' 
}

到目前为止一切顺利,但如果我们在其声明下调用函数:

{
  function foo(location) {
   console.log('foo is called ' + location);
  }
  foo('inside'); // works correctly and logs 'foo is called inside' 
}
foo('outside');  // 'foo is called outside' 

突然函数不再是 block 作用域,而是函数作用域。它的行为与 var 完全一样,后者是函数作用域:

console.log(typeof foo);//undefined
{
    var foo = function(location) {
        console.log('foo is called ' + location);
    }
    console.log(typeof foo);//function
}
console.log(typeof foo);//function

我的问题是:函数的范围是什么?如果它的范围是功能,那么提升有什么问题?或者它是正确的实现,但我没有正确理解某些内容?

由于一些困惑,我创建了以下示例: 1一切都很好

foo();//logs 'bar' because of hoisting
function foo(){
        console.log('bar');
}

1b 一切正常,函数表达式没有提升

foo();//Error! foo is declared, so it was hoisted, but without its body, so it cannot be called
var foo = function(){
    console.log('bar');
}

2 这会引起混淆。如果函数范围是函数,那么为什么下面的函数声明没有被提升?由于某些奇怪的原因,它像 1b 一样工作(函数表达式,而不是函数声明)

foo();//Error! foo is declared, so it was hoisted, but without its body, so it cannot be called
{
    function foo(){
        console.log('bar');
    }
}

3 如果函数作用域是 block ,那么为什么函数在 block 外可用?

{
    function foo(){
        console.log('bar');
    }
}
foo();//logs 'bar'

3b 一切都很好。让作用域为 block ,所以在 block 外不可用

{
    let foo = function(){
        console.log('bar');
    }
}
foo();//Error, not declared

最佳答案

函数声明函数作用域,如下所示

function test() {
  function a() {
    console.log("outer a");
  }
  if (1) {
    function a() {
      console.log("inner a");
    }
    function b() {
      console.log("inner b");
    }
    a(); //will call inner a
  }
  a(); //will call inner a
  b(); //will call inner b
}
test();

输出

inner a

inner a

inner b

编辑 - 场景 - 内部函数声明未将值提升到顶部

此外,函数声明似乎是函数作用域,它的提升(值(value))只发生在 block 内,这这就是为什么 b(函数中的第二个语句)打印 undefined,而 a 打印为 function

function test() {
  console.log(a); //prints outer a
  console.log(b); //undefined 
  function a() {
    console.log("outer a");
  }
  if (1) {
    function a() {
      console.log("inner a");
    }

    function b() {
      console.log("inner b");
    }
    a(); //will call inner a
  }
  a(); //will call inner a
  b(); //will call inner b
}
test();

输出

function a() { console.log("outer a"); }

undefined

inner a

inner a

inner b

关于javascript - JavaScript函数声明作用域是 block 还是函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48924125/

相关文章:

javascript - $scope 中的值在 location.path 之后不可见

javascript - 从模块外部调用函数 - 参数未正确传递

c# - 启动/更新变量范围

function - 如何在 PostgreSQL 函数的插入查询中插入参数值?

php - 如何在php中分解传入的短信并将其插入数据库

reactjs - 在 Jest 中使用范围包

c++ - 复制到 QMap 时出现 QString 错误。范围问题?

javascript - 在 Neo4j 中创建批量节点时如何生成唯一的 UUID

javascript - 发送带有 json 的 html 文件并让浏览器重新加载该 json 而无需重新加载页面

javascript - 滑动 jQuery 菜单