通过 Javascript 中的变量范围维护变量

Posted

技术标签:

【中文标题】通过 Javascript 中的变量范围维护变量【英文标题】:Maintaining variables through variable scope in Javascript 【发布时间】:2011-11-08 15:27:31 【问题描述】:

我在使用我正在制作的 Node.js 应用程序中处理变量范围时遇到了麻烦,通常我了解变量范围在函数中/周围的工作原理(在本例中为匿名回调函数)。

我正在与之斗争的是通过匿名回调链/漏洞维护变量的最佳方法是什么。通常我可以将变量传递给函数,但是因为我使用的是猫鼬(mongodb ORM),所以我不能传递我自己的变量。因此不得不在每一步中一遍又一遍地定义变量回调。

最好的方法是什么?

下面是我的代码,当我想将它们用于推文时,我最终会得到未定义的变量:

var userBid = tag.user;

User.find(id: userAid, function(err, userA)

  if (err) console.log("Error getting user A for tweeting ", err)
  else 
    var userAName = userA.twitter.screenName;
    var userBid2 = userBid;
    User.find(id: userBid2, function(err, userB)

      if (err) console.log("Error getting user B for tweeting ", err)
      else 

        var action = "@"+ userAName + " just claimed some of @" + userB.twitter.screenName + " 's turf as their own.";

        twitterClient.updateStatus(action, function(err, resp)
          if (!err) 
            console.log("Tweeted: ", action );
           else 
            console.log("TwitBot error:", err);
          
        );
      
    );
  
 );

当然有更好的方法来处理这个...... 非常感谢任何帮助。

【问题讨论】:

这不是 php/C/Java!您不必传递变量。它们将始终通过范围查找链可用...只需在范围的顶层声明一次(就像您现在拥有的那样),然后您可以从这些函数内部访问它们。 不需要把它们从兔子洞里传下去!! 嗯...如果是这种情况,那为什么我的变量未定义?绑定/柯里化的原因是什么,请参阅下面的@Raynos 答案 迟到总比不到好:您的 userBid 定义正确,应该可以在您的查询中访问。它是在您的函数之外定义的,因此将在下面的函数内部可见。只要确保变量实际上定义正确并且 tag.user 没有未定义。一个简单的 console.log(userBid) 应该可以解决这个问题。 【参考方案1】:
User.find(
    id: userAid
, function(err, userA) 
    if (err) throw err;
    else 
        User.find(
            id: tag.user
        , (function(userAName, err, userB) 
            if (err) throw err;
            else 
                var action = "@" + userAName + " just claimed some of @" + userB.twitter.screenName + " 's turf as their own.";
                twitterClient.updateStatus(action, function(err, resp) 
                    if (!err) 
                        console.log("Tweeted: ", action);
                     else 
                        console.log("TwitBot error:", err);
                    
                );
            
        ).bind(null, userA.twitter.screenName));
    
);

要么使用闭包作用域(tag.user 可通过闭包获得),要么使用 .bind 将变量绑定到函数。

例如,我们通过以下方式将userAName 变量柯化到匿名函数中

(function(userAName, normal, arguments, here) 

).bind(null, userAName));

【讨论】:

感谢您的回答,我对此部分感到困惑:(function(userAName, err, userB) 我担心看到此回调被第三方 (mongoose) 触发,我不能只对 @987654327 @ in,我的印象是第一个参数是 err ... 或者按照您的建议进行操作是否安全? @Christopher 这就是.bind 的工作方式。它返回一个锁定第一个参数的新函数,并将其余参数放在第一个参数之后

以上是关于通过 Javascript 中的变量范围维护变量的主要内容,如果未能解决你的问题,请参考以下文章

d3 javascript中的变量范围

在 C# Web 浏览器中创建 javascript 变量全局范围

JavaScript中的变量范围是什么?

在同一类中的 setTimeout 期间维护变量

Javascript,回调函数中的变量范围之外?

地理定位功能中的 JavaScript 变量范围