【问题标题】:Node JS comma assignment节点 JS 逗号赋值
【发布时间】:2017-01-24 07:29:57
【问题描述】:

我正在阅读blog post 并遇到以下代码sn-p:

var fs = require('fs'),
    filenames,
    i,
    processId;

filenames = fs.readdirSync(".");
for (i = 0; i < filenames.length; i++) {
    console.log(filenames[i]);
}
console.log("Ready.");

processId = process.getuid();

我很好奇:

var fs = require('fs'),
    filenames,
    i,
    processId;

这是逗号运算符的示例吗:

逗号运算符计算其两个操作数(从左到右)并返回第二个操作数的值。

如果是这样,我仍然不明白发生了什么。以下语句是否与编写类似的内容相同:

var fs = require('fs')
var filenames;
var i;
var processId;

以下是否有效:

var foo = require('./foo.js'),
    bar = require('./bar.js'),
    baz = require('./baz.js'),
    input = "some string",
    i,j,k;

并评估为:

var foo = require('./foo.js'),
var bar = require('./bar.js');
var baz = require('./baz.js');
var input = "some string";
var i;
var j;
var k;

【问题讨论】:

  • 请不要明显改变您的问题!
  • 特别是在发布一些答案时。

标签: javascript node.js


【解决方案1】:

这不是逗号运算符。逗号是var 关键字语法的一部分。指定var 关键字以获取以逗号分隔的变量列表。

此功能在规范中称为VariableDeclarationListhttp://www.ecma-international.org/ecma-262/7.0/index.html#sec-variable-statement

var 关键字语法指定为:

Syntax

VariableStatement[Yield]:
    var VariableDeclarationList[In, ?Yield];

VariableDeclarationList[In, Yield]:
    VariableDeclaration[?In, ?Yield]
    VariableDeclarationList[?In, ?Yield], VariableDeclaration[?In, ?Yield]

VariableDeclaration[In, Yield]:
    BindingIdentifier[?Yield] Initializer[?In, ?Yield]opt
    BindingPattern[?Yield] Initializer[?In, ?Yield]

如果您不熟悉 BNF 或 RBNF 表示法。上面的规范意味着:

  1. VariableStatement 定义为:

    1. 字符串var 后跟VariableDeclarationList
  2. VariableDeclarationList 被定义为:

    1. 变量声明或
    2. 变量声明列表,变量声明
      • 注意:这是一个递归定义。基本上它定义了一个 VariableDeclaration、VariableDeclaration、VariableDeclaration 的无限列表...
  3. VariableDeclaration 定义为

    1. BindingIdentifier 后跟可选的 Initializer 或
    2. BindingPattern 后跟一个初始化器
      • 注意:此 BindingPattern 定义适用于新的 ES6 解构赋值 ([a,b,c] = ...)

BindingIdentifierBindingPatternInitializer 的定义在规范的其他地方指定。

BindingIdentifier的定义基本上是一个变量名。所以有效的BindingIdentifiershelloxy2 但不是for(因为它是一个关键字)或1k(因为它以数字开头)。

我暂时忽略BindingPattern 的定义,因为理解变量列表定义并不是绝对必要的。

Initializer 的定义是符号= 后跟一个表达式。基本上= 后跟任何 javascript 代码。

所以,VariableDeclaration(不是var 关键字,只是其中的一部分)简单定义为:

anyVariableName = anything

anyVariableName // remember, Initializer is optional

var 关键字定义为:

var VariableDeclaration

var VariableDeclaration, VariableDeclaration, VariableDeclaration ...

所以。 var 关键字语法的有效示例包括

var x;

var x = 12;

var x,
    y = "hello",
    z;

var x = 0,
    y,
    z=100;

等等

当我们包含BindingPattern 定义时,var 关键字语法的有效示例还包括:

var x=10,
    [a,b,c] = [100,200,300],
    i,
    j;

var {x,y,z} = {x:10,y:20,z:30},
    a = 2,
    b,
    c,
    [i,j,k]=["hello","cruel","world"];

补充说明:

请注意,VariableDeclaration 也可以在没有 var 关键字的情况下发生。例如:

a = 40; // if this is the first time a is defined then it is 
        // automatically created as a global variable

在这种情况下,由于没有 var 关键字,因此出现的任何逗号都不会成为 var 语法的一部分。这意味着如果没有 var 关键字,逗号是逗号运算符:

a = 10, b = 50; // comma operator

【讨论】:

  • 对于继承 C 风格语法的语言,我不喜欢的一件事是符号可能具有不同的含义,具体取决于它所属的语法。
  • 我的解释正确吗?能举个小例子吗?
  • @mbigras:我认为没有必要举一个例子,因为你自己在你的问题中提供了一个例子。
  • 是否可以使用此 sytnax 进行多项分配?例如,在 ruby​​ 中,我可以写 a, b, c = 42, "foo", "bar"。只是想知道这是否与正在发生的事情相同。
  • @mbigras 否。该列表只是多个用逗号分隔的声明。所以你必须做多个作业a=42,b="foo",c="bar"。您可以通过数组解构进行多个赋值,但这是一种不同的语法
【解决方案2】:

不,它不是逗号运算符。

var a="1,2,3", b=[1,2,3]; // No comma operators in this line

if (a == b)
  alert("Yes"), a = null; // Comma operator

if (a += 10, b) // Comma operator
  b[1,2] = a;   // Comma operator

a = (1,2,b[3]); // Comma operator

var 语句中的逗号分隔不同的变量,所以是的,它相当于多个变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多