JavaScript函数声明范围是块还是函数?

时间:2018-02-22 09:45:09

标签: javascript function scope

MDN说"函数声明在声明发生的块内的范围也受到限制" (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' 

突然,功能不再是阻止范围,而是功能范围。它的行为与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如果功能范围是阻止,那么为什么功能在块外可用?

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

3b一切都很好。让范围是阻止,因此它在块

之外不可用
{
    let foo = function(){
        console.log('bar');
    }
}
foo();//Error, not declared

1 个答案:

答案 0 :(得分:1)

功能声明仅限功能范围,如下所示



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();




输出

  

内心

     

内心

     

内在b

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

此外,似乎函数声明功能范围,它的提升(值)仅发生在块中,这就是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("外部"); }

     

<强>未定义

     

内心

     

内心

     

内在b