如果匿名 JavaScript 函数可以访问所有变量,那么常规函数呢?

If anonymous JavaScript functions can access all variables, what about regular functions?

在 Javascript 中,函数变量是局部的,除非它们没有用 "var" 声明。也就是说,除非这些函数是匿名的(比如 setInterval 和 setTimeout 中使用的函数。在那种情况下,它们可以全局访问调用匿名函数的范围内的所有可用变量。

那么常规函数呢?有什么方法可以让他们也访问所有变量吗?我问这个是因为在某些情况下,在 1 个具有许多变量的父函数下具有非常复杂的函数,我突然不得不将它们从匿名函数转换为常规函数。

例如,假设我原来的匿名函数名为 alert,现在我想通过常规函数来完成:

myFunction()
function myFunction() {
    var a='b' //,b=...,c=...,d=...,e=...,f=...,g=...,h=...,i=...,j=...,k=...
    setInterval(function(){ alert(a) }, 3000) // Works even though a is local
    setInterval(function(){ dummy() }, 3000) // Fails, but would work if I used dummy(a).
    // But then I'd have to use dummy(a,b,c,d,e,f,g,h,i,j,k,...)
}

function dummy() { // It would have worked had I used dummy(a)
    alert(a)
}

问题不是关于匿名函数的问题。走这两行:

 setInterval(function named (){ alert(a) }, 3000);
 setInterval(function(){ alert(a) }, 3000);

两者都有效,但一个已命名,一个未命名。这里真正的问题是范围界定,adummy 不可见,因为 dummya 的范围之外声明:

  { // brackets start a scope
    let a = "b"; // a gets declared in this scope
    //...
  } // scope ends

  function dummy() { /*..*/ } // outside of scope

要解决这个问题,请将 dummy 移到 a 的范围内:

 function myFunction() { // start of scope
   let a = "b"; 
   setInterval(function(){ dummy() }, 3000);

   function dummy() { 
    alert(a); // a can be accessed as it is inside of the scope
   }
 } // end of scope

(我使用 let 而不是 var 因为它更严格,因此更容易证明范围规则)