【问题标题】:how to achieve Lexical scoping in non-anonymous/declared functions in Javascript如何在Javascript中的非匿名/声明函数中实现词法作用域
【发布时间】:2017-07-12 09:07:52
【问题描述】:

词法作用域是 Javascript 中最令人困惑的主题之一,我有一种情况是我无法合理化错误,或者我应该说为什么代码不起作用。

这是一个例子:

我已经在匿名函数中记录了name 变量并且它工作正常。

function print() {
    var name = 'foo bar';
    printer(function(){
        console.log(name)
    });
}

function printer(callback) {
    callback();
}

print();

结果:foo bar

但是因为我不想声明一个匿名函数。所以,我已经单独声明了。

function print() {
    var name = 'foo bar';
    printer(callbackHandler);
}

function callbackHandler() {
    console.log(name)
}

function printer(callback) {
    callback();
}

print();

结果:ReferenceError:名称未定义

谁能解释这个问题并提供解决方案?

非常感谢您的宝贵时间!!

【问题讨论】:

  • 如我所见,您将范围从“print”传递到“callbackHandler”,通常该名称不存在,它只存在于“print”范围内。另一个想法是使用.bin,然后就可以用范围调用它(这不是teste,然后是apply或call)
  • 词法作用域并不令人困惑。当您声明一个变量(使用 let)时,它可以在任何地方访问。 { 和 } 。太简单。如果您想在其他地方访问它,请以某种方式传递它(闭包、参数、绑定参数等)

标签: javascript


【解决方案1】:

当传递命名或匿名函数作为需要当前作用域变量的参数时,您必须将其“转换”为绑定函数。您可以通过Function.prototype.bind 调用来实现。在你的情况下,像这样:

function print() {
    var name = 'foo bar';
    printer(callbackHandler.bind(null, name));
}

function callbackHandler(name) {
    console.log(name)
}

function printer(callback) {
    callback();
}

print();

【讨论】:

    【解决方案2】:

    JavaScript 有两种作用域,本地和全局。如果一个变量在一个函数中,它是该函数的局部变量。但是,该变量可以绑定到另一个函数(匿名或命名)并且可供该函数使用,只要该函数是在该本地范围内定义的。

    function printer( callback ) {
         callback();
      }
    
    
    function print() {
    
      var name = "testing and all is well";
    
      function callbackHandler() {
         console.log( name );
      }
      
      printer( callbackHandler );
    }
    
    print();

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-19
      • 1970-01-01
      • 1970-01-01
      • 2011-03-11
      • 1970-01-01
      • 2010-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多