两个javascript语法问题

时间:2011-09-16 00:31:33

标签: javascript

这些天我正在阅读一些javascript源代码,但是我发现了一些我无法理解的语法。

1)for-in循环

var c;
var obj={name:'test',age:33};

for(var e in c={},obj){
    console.info(e+' = '+obj[e]);
}

2)条件运算符(?:)

通常,我们以这种方式使用此运算符:

x > 0 ? x*y : -x*y

但是我看到过这样的代码:

x > 0 ? (x*y,z=bar,..other expressoin) : (-x*y)

但是如果我将逗号更改为冒号则不起作用,它会抛出错误。

4 个答案:

答案 0 :(得分:8)

在这两种情况下,都使用了comma operator [MDN]

  

如果要在需要单个表达式的位置包含多个表达式,可以使用逗号运算符。此运算符的最常见用法是在for循环中提供多个参数。

specification

  

11.14 Comma Operator ( , )

     

<强>语法

Expression :
    AssignmentExpression
    Expression , AssignmentExpression
     

(...)

     

<强>语义

     

生产 Expression:Expression,AssignmentExpression 评估如下:

     
      
  1. lref 成为评估Expression的结果。
  2.   
  3. 调用GetValue( lref )。
  4.   
  5. rref 成为评估AssignmentExpression的结果。
  6.   
  7. 返回GetValue( rref )。
  8.   

这仅仅意味着表达式的整个“列表”结果返回最后一个表达式的结果

在您给出的示例中,它用于side effects [Wikipedia],即评估每个表达式 一般来说,我会说这不是一个好的风格,正如你所注意到的,更难以理解

for(var e in c={},obj)

相同
c = {};
for(var e in obj)

似乎没有添加任何值。更好的方法是在第一行初始化cvar c = {};

对于条件运算符:如果x > 0true,则计算所有表达式并返回最后一个表达式的结果。在这种情况下,使用正常的if语句会更好(更容易理解)。

再次,逗号运算符甚至条件运算符似乎只是因为它们的副作用而使用:通常条件运算符应该只返回一个值但不执行任意表达式(单个函数调用返回值可能是一个例外)。


正如MDN文档所述,它更常用于for循环来初始化多个变量:

for(var i = 0, l = array.length; i < l; i++)

答案 1 :(得分:1)

在Javascript中,您可以定义变量,如:

var obj1 = { a: 2, b: 4, c: 6};
var obj2 = { x: 1, y: 3, z: 5};

或者,您可以用逗号分隔声明,如下所示:

var obj1 = { a: 2, b: 4, c: 6}, obj2 = { x: 1, y: 3, z: 5};

现在,for循环通常类似于:

for(var key in obj1) { console.log(key); }

但是,如果你在'in'之后用逗号链接它,它将允许它(就像分配时一样),但是会在链中的最后一个对象上运行循环。

var key, obj1 = { a: 2, b: 4, c: 6}, obj2 = { x: 1, y: 3, z: 5};

// will output 'a', 'b' and 'c'
for(key in obj2, obj1) { console.log(key); }

// will output 'x', 'y' and 'z'
for(key in obj1, obj2) { console.log(key); }

这意味着你可以在for中指定值,然后在另一个对象上循环。

var key, obj3; // obj3 === null

var obj1 = { a: 2, b: 4, c: 6}, obj2 = { x: 1, y: 3, z: 5};

// will output 'a', 'b' and 'c'
for(key in obj3 = { j: 9, k: 8, l: 7 }, obj1) { console.log(key); }

// obj 3 is now { j: 9, k: 8, l: 7 }

好的,现在是ternary operators。如果上述内容有意义,那么就应该这样。

三元操作就像是单行的if语句。你不能将分号放在一行中,因为它会变成两行或更多行。但是在逗号分隔的声明周围加上(),它仍然被认为是一行。

所以这是有效的:

x > 0 ? a = 1 : a = 2;

这是有效的:

x > 0 ? (a = 1, b = 2) : (a = 2, b = 1);

但事实并非如此,因为逗号摒弃了对三元的解释:

x > 0 ? a = 1, b = 2 : a = 2, b = 1;

但我不建议在三元组中设置值,除非它看起来像:

a = x > 0 ? 1 : 2;

:)

答案 2 :(得分:0)

第一个?不知道。第二?它就像你的典型内联,除了它执行多个表达式而不是一个

x > 0 ? (doThis(),doThat(),x=2) : (again(),another(),y=5);

答案 3 :(得分:0)

第一个不是初始化器吗?

var c;
var obj={name:'test',age:33};

for(var e in c=[], obj){
    console.info(e + ' = ' + obj[e]);
    c.push(e);
}

console.info(c);

现在,为什么你这样做......我不确定。