【问题标题】:variable in closure but not able to access闭包中的变量但无法访问
【发布时间】:2016-06-24 00:08:44
【问题描述】:
var net = require('net');
var redis = require('redis'); 
var redisClient = redis.createClient("redis://localhost:6379");

redisClient.on("connect",function(){
    console.log("Connected to Redis");
});

net.createServer(function(socket){
    console.log('CONNECTED: ' + socket.remoteAddress +':'+  socket.remotePort);
    var id = '';
    socket.on('data',function(data){
        console.log(id);
        if(id == '')
              test();
        else
           //do something else
    });
}).listen(10000,'');


function test(){
     redisClient.hgetall('12345',function(err,res){
         id = res.id;
     });
}

在这段代码中,为什么当我调用函数测试时变量 id 没有关闭?它给出的错误 id 在测试函数中是未定义的。我是否以错误的方式理解闭包?

【问题讨论】:

  • 你对闭包的理解是错误的。 JavaScript 作用域是词法和静态的。调用函数不会使被调用函数可以使用局部范围变量。
  • @Pointy 我已经编辑了代码。对于第一个数据包,我使用之后收到的数据中的详细信息获取 id,而无需对 redis 进行任何调用,我想继续代码。我可以做这样的事情吗?
  • 不,您仍然遇到完全相同的问题。
  • 是的,但如果我添加 var self = this.并通过此功能测试使用 self.id 更改 id。这是一个很好的做法。 ?
  • 如果你让id不是一个局部变量而是一个对象的一个​​属性,你可以将对该对象的引用传递给test(),然后异步调用可以修改属性值.

标签: javascript node.js closures


【解决方案1】:

函数test——以及所有其他函数——只能看到全局变量、在函数本身中定义的变量以及在函数定义的封闭范围内定义的变量。

您在调用该函数的范围内看不到变量。如果您想让函数可以访问这些变量,则必须将它们作为参数传递。

【讨论】:

  • 有什么方法可以从函数更改父范围内的变量。即我可以从测试函数中更改 id 吗?
  • @user3508612 在这种情况下,不 - test() 函数本身正在调用另一个异步操作。您可以从同步函数返回值,但在这种情况下,它只是没有意义。
  • 我已经更新了代码。我可以这样做吗?
【解决方案2】:

是的,闭包不能看到在单独的函数中定义的变量。变量是词法(函数)范围的(如 lex82 和 Pointy 所述)。

您只能在 test() 中定义var id = '' 或在 test() 函数中传递 id 变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 2011-12-03
    • 2016-01-18
    • 2023-04-06
    • 2019-06-07
    • 1970-01-01
    • 2011-04-12
    相关资源
    最近更新 更多