Javascript:为什么我可以访问在全局范围内的函数内声明的内部名称?

时间:2017-01-18 15:30:19

标签: javascript scope closures

在chrome开发控制台中, 我创建了一个带有两个嵌入函数的函数f

> var a = 'ga';
  var b = 'gb';
  var c = 'gc';
  var f = function(){
      var a = 'fa';
      var b = 'fb';
      ff = function(){
          var a = 'ffa';
          fff = function(){
              console.log("a,b,c is: " + a + "," + b + "," + c);
          };
          fff();
      };
      ff();
  };
< undefined

然后,我将ff输入到控制台,发现我仍然可以访问它, 虽然它是在f

的内部范围内定义的
> ff     // why can I still access the name ff ?
< function (){
         var a = 'ffa';
         fff = function(){
             console.log("a,b,c is: " + a + "," + b + "," + c);
         };
         fff();
     }

名称fff

也是如此
> fff   // why can I still access the name fff ?
< function (){
             console.log("a,b,c is: " + a + "," + b + "," + c);
         }

我是一名C / C ++开发人员,目前正忙于javascript。

这种现象对我来说似乎很难理解 因为在Cpp中,访问内部范围内的名称是错误的 例如:

#include <iostream>

using namespace std;

int main(int argc, char *argv[]){
    auto f = [](){
        std::cout << "in f() now" << std::endl;
        auto ff = [](){
            std::cout << "in ff() now" << std::endl;
            auto fff = [](){
                std::cout << "in fff() now" << std::endl;
            };
            fff();
        };
        ff();
    };

    f(); //it's okay
    ff(); // not okay, error: use of undeclared identifier 'ff'
    fff(); // not okay too, error: use of undeclared identifier 'fff'

    return 0;
}

即使在python中,我们也不能这样做:

def f():
    print("in f() now")
    def ff():
        print("in ff() now")
        def fff():
            print("in fff() now")
        fff()
    ff()

f()   # okay
ff()  # NameError: name 'ff' is not defined
fff() # NameError: name 'fff' is not defined

所以,我很想知道为什么可以在内部范围内访问该名称,即使我不在其中

提前致谢!

2 个答案:

答案 0 :(得分:5)

在全局上下文中生成没有var的变量。

  

在执行赋值时,为未声明的变量赋值会隐式地将其创建为全局变量(它将成为全局对象的属性)。

答案 1 :(得分:3)

您尚未使用var来声明fffff。如果你没有声明它们,它们会自动被全局声明,而不是在本地声明。

所以我没试过,但这应该更像你之后的......

  var a = 'ga';
  var b = 'gb';
  var c = 'gc';
  var f = function(){
      var a = 'fa';
      var b = 'fb';
      var ff = function(){
          var a = 'ffa';
          var fff = function(){
              console.log("a,b,c is: " + a + "," + b + "," + c);
          };
          fff();
      };
      ff();
  };