【问题标题】:Variable declaration and initialization in JavaScript/Node.JSJavaScript/Node.JS 中的变量声明和初始化
【发布时间】:2016-11-01 00:59:03
【问题描述】:

我在 JavaScript 中看到了不同的编码格式/样式推荐。其中之一是在每行末尾省略,;,除非在JSON 对象中使用,。另一种是仅使用var 来声明变量并缩进第二个变量。

我采纳了这两个建议,这给我带来了一个有趣的错误,我想深入了解这个问题。

初始化

var max = 2
    arr = []
    wait = 10

//Preset arr with simple object {id:i}
for(var i = 0; i < max; i++) arr.push({id:i})

主要功能

function simulate(idIn, callback) {
    var msg = idIn 
        id = idIn

    logger.info(idIn, 'simulate', JSON.stringify({id:id, idIn:idIn}))
    setTimeout(function() {
        var obj = {id:id, idIn:idIn}
        logger.info(idIn, 'init', JSON.stringify(obj))
        callback()
    }, wait)
}

并行执行

async.map(arr, function(item, cb) {
    logger.info('map', JSON.stringify(item))
    simulate(item.id, cb)
}, function(err, result) {})

输出

info: map {"id":0}
info: 0 'simulate' '{"id":0,"idIn":0}'
info: map {"id":1}
info: 1 'simulate' '{"id":1,"idIn":1}'
info: 0 'init' '{"id":1,"idIn":0}'  //id is overwritten here 
info: 1 'init' '{"id":1,"idIn":1}'

从输出中可以看出,在等待期间,局部变量id 被传入的idIn 参数值覆盖。我通过在simulate 函数的变量声明中简单地添加, 解决了这个问题。

    var msg = idIn, //Added comma here. 
        id = idIn

我想这意味着如果您只想使用一个 var 关键字,则不能在多个变量声明中省略 ,。我试图了解当, 被省略时第二个变量id 会发生什么?这会改变它的范围还是让它变成别的东西?

【问题讨论】:

  • 省略 , 运算符会导致自动分号插入 (ASI):var msg = idIn; id = idIn; 现在省略了 var 关键字。由于您的变量声明在本地范围内,id 获得一个全局变量。
  • 我发现这篇文章可能对你有所帮助:benalman.com/news/2012/05/multiple-var-statements-javascript
  • 无论您在哪里获得此建议,都不要再访问该网站。
  • 值得一提的是,声明 'use strict' 可以帮助您更快地发现这一点。
  • 谢谢大家。这消除了疑虑。

标签: javascript node.js variables scope


【解决方案1】:

当逗号丢失时,javascript 解释器假定您忘记了; 并自行添加它。现在的代码如下所示:

var msg = blabla;
id = x;

所以下一条语句就变成了id = x;。所以 javascript 只需将值 x 放在全局/父范围内的现有变量 id 中。

当逗号没有丢失时,解释器无需假设 - 它知道您声明了一个 new 变量 id,其值为 x

Javascript 解释器无法猜测您是否遗漏了分号或逗号,它假定您遗漏了分号,并且在某些情况下会产生意想不到的结果。

我建议你不要继续写这样的代码,至少不是故意的。

【讨论】:

  • 快速说明:自动分号插入后id 不再是本地变量,而是全局变量。
  • 即使在父范围内有一个变量id? :0
  • 前提是这个父作用域是全局作用域id = x只是变异了全局变量id
  • 哦,我只是没有假设simulate 函数在全局范围内,因为它可能是从他的代码中的任何地方复制的,所以我回答得更笼统。当然你是对的,谢谢!
【解决方案2】:

JavaScript 与所有编程语言一样,都有其语法规则。
我建议您在遵循任何建议之前先研究它们(恕我直言,您遵循的建议很糟糕)。

其中一条规则是;(用于分隔语句):

  • 必需,当您在同一行上有两个(或更多)语句时
  • 可选,如果语句后跟换行符

另一个规则说你必须使用var 关键字来声明一个变量,它的范围取决于这个声明发生的地方。

  1. 当你在函数中声明一个变量时,例如

    function f() {
        var v;
    }
    

    变量v 将有一个本地范围,它只能在函数f内访问。

  2. 否则,当你在函数之外声明一个变量时,例如

    var v;
    

    变量v 将具有全局范围,同一页面上的每个脚本和函数都可以访问它。

  3. 即使您为尚未声明的变量赋值,例如

    function f() {
        v = "hello world";
    }
    

    变量v会自动变成一个全局变量。

所以,既然在你的代码中你已经写了:

var msg = idIn 
    id = idIn

意思是:

var msg = idIn;
id = idIn;

它使id 成为一个全局变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多