zoukankan      html  css  js  c++  java
  • JavaScript中的逗号运算符

    JavaScript逗号运算符 

          阅读本文的前提,明确表达式、短语、运算符、运算数这几个概念。

          所谓表达式,就是一个JavaScript的“短语”,JavaScript解释器可以计算它,从而生成一个值。表达式分为以下三种形式:

     1)直接量:1.7是一个数字直接量,“JavaScript权威指南”是一个字符串直接量;

     2)变量

     3)复杂表达式:合并1)、2)中的表达式,创建比较复杂的表达式。例如:1.7是表达式,i是表达式,而1.7+i,也是表达式,它是两个简单表达式(一个直接量表达式,一个变量表达式)的和。在此例中,“+”是一个运算符,用于将两个简单表达式合并起来组成一个复杂的表达式。

          所谓运算符和运算数?可根据运算数的个数来对运算符进行分类,一元运算符:只有1个运算数,如:-3中的“-”对运算数取反,只包含一个运算数,为一元运算符。二元运算符:有2个运算数,如“+”。三元运算符:包含3个运算数,将三个表达式合并成一个复杂的表达式,如“?"。

         接下来进入正题...... 

         逗号运算符的特性及作用:逗号运算符的作用是将若干表达式连接起来。它的优先级是所有运算符中最低的,结合方向是自左至右。

         逗号表达式:
               一般形式:表达式1,表达式2,表达式3,......表达式n

               求解过程:先计算表达式1的值,再计算表达式2的值,......一直计算到表达式n的值。最后整个表达式的值是表达式n的值。 

         看下面几个例子:

     1)x = 8*2, x*4; /*整个表达式为逗号表达式,它的值为64,x的值为16*/

     2)(x = 8*2, x*4) , x*2; /*整个表达式为逗号表达式,它的值为32,x的值为16*/

     3)x = (z=5,5*2); /*整个表达式为赋值表达式,它的值为10,z的值为5*/

         请注意:并不是所有的逗号都要看成逗号运算符,如在函数调用时,各个参数是用逗号分隔开的,这里的逗号并不是逗号运算符。如:printf("%d, %d, %d", x, y, z);

     4)如下代码所示

    var a = 10,
        b = 20;
    function CommaTest() {
        return a++, b++, 10;
    }
    var c = CommaTest();
    alert(c); // 返回10

          使用逗号运算符的场景归纳如下:

    1. for循环中逗号运算符

          逗号运算符的常见用法是在for循环的增量表达式中使用。例如:

    var i,j=5,k;
    for(i=0; i<10; i++,j++) {
        k = i + j;
    }

          在每次通过循环的结尾时,for语句只允许单个表达式被执行。逗号运算符允许将多个表达式视为单个表达式,因此这两个变量都递增。

    2. 逗号运算符与函数调用运算符的冲突

          在JavaScript中函数调用确实是函数调用运算符。它很特殊,因为其它编程语言资料中从来没有这个叫法。

          函数调用运算符将计算它的每一个运算数,第一个运算数指定为函数名(括号前),而括号中的所有运算数的值将传递给这个函数作为参数。

          接下来看一个逗号运算符和函数运算符冲突的例子以及解决的方法。

    alert(2,5);  //2
    alert((2,5)); //5

          由于逗号运算符在JavaScript中的优先级是最低的,因此函数运算符将先于逗号运算符运行,上述代码中第一个alert函数弹出2。 解决方法如第二个alert函数所示,加上括号,保证逗号运算符先运行。

    3. 逗号运算符和赋值运算符冲突

    var a = 20;
    var b = ++a, 10;
    console.log(b);

          上述代码报错:由于逗号运算符要求它的运算数为复杂表达式或简单 表达式(如变量或直接量),赋值运算符先于逗号运算符执行,使逗号运算符左边不是一个运算数或表达式,而是含有var关键字的语句,因此报错。解决方法:只需加上括号,即var b = (++a, 10),保证逗号运算符先执行即可。

          再看几个示例,后两个示例略为奇葩。

          示例一

    console.log((0,9));  //9
    console.log((9,0));  //0
    if((9,0)) console.log("no");
    if((0,9)) console.log("yes");  //yes

          示例二:交换变量,无需第三个变量

    var a = 'a', b = 'b';
    //method1
    a = [b,b=a][0];
    //method2
    a = [b][b=a,0];

          分析:a = [b,b=a][0]中,[b,b=a]表示一维数组,[0]表示下标;a = [b][b=a, 0],其中[b]表示一维数组,[b=a, 0]中按逗号运算符处理,返回0,当做下标。

          在这个例子中,我一直将在[b,b=a][0]和[b][b=a, 0]视作二维数组,这不对的。

          一维数组形式:[1,2,3][0]   //取得值1      

          二维数组形式:[[1,2,3],[4,5,6]][1][1]     //取得值5 

          不过上述两种数组表示形式很少用。

          示例三:简化代码,不过可读性差

    if(x) {
        foo();
        return bar();
    else {
        return 1;
    }
    // equal to 
    return x ? (foo(), bar()) : 1;

    时间:2014-10-20

    地点:合肥

    引用:http://msdn.microsoft.com/zh-cn/library/ie/9b37css7(v=vs.94).aspx 

            http://www.feeldesignstudio.com/2013/09/javascript-comma-operator 

            http://www.cnblogs.com/pinocchioatbeijing/articles/2343736.html 

  • 相关阅读:
    【干货分享】C# 实体类生成工具
    ASP.NET Core部署系列二:发布到CentOS上
    ASP.NET Core部署系列一:发布到IIS上
    微信公众号开发:用户管理
    微信公众号开发:自定义菜单
    像使用SQL一样对List对象集合进行排序
    使用JRebel插件实现SpringBoot应用代码热加载
    Java Stream函数式编程图文详解(二):管道数据处理
    SpringBoot生命周期管理之停掉应用服务几种方法
    本月16日SpringBoot2.2发布,有哪些变化先知晓
  • 原文地址:https://www.cnblogs.com/sun-mile-rain/p/4037916.html
Copyright © 2011-2022 走看看