表达式与运算符

表达式

[ 原始表达式 ] 表达式的最小单位,可以分为直接量、关键字和变量。

1.23    // 数字直接量
“hello”    // 字符串直接量
/pattern/    // 正则表达式直接量

true    // 返回一个布尔值:真
false    // 返回一个布尔值:假
null    // 返回一个值:空
this    // 返回“当前”对象

i    // 返回变量 i 的值
sum    // 返回 sum 的值
undefined    // undefined 是全局变量,和 null 不同,它不是一个关键字

[ 表达式?↓ ] 简单来说,是由操作符(又称,运算符)以及一个或多个操作数组成的一个语句。

1
1 + 2
(1+2) + (4-3)
(1+2) + (4-3) || !flag

运算符

[ 运算符语法?!JS 操作符的与众不同之处在于,它们能够适应于很多值,如字符串、数值、布尔值,甚至是对象。

在应用于对象时,相应的操作符通常会调用对象的 valueOf() 和(或) toString() 方法,以便取到可以操作的值。


  • 算术运算符(+    -    *    /    %    **)
    • 一元运算符(++    --    +    -)
  • 赋值运算符(=    *=    /=    %=    +=    -=)
  • 关系(比较)运算符(>    <    >=    <=)
    • 相等运算符(==    !=    ===    !==)
  • 位操作符(~    &    |    ∧    <<    >>    >>>)
  • 逻辑(布尔)运算符(!    &&    ||)
  • 其他:条件运算符(?:)、逗号、() 和 void运算符

[1] 算术运算符:JS 中算术操作主要通过算术运算符来实现,包括一元算术运算符和二元算术运算符。

[ 一元运算符?↓ ]  一些只需要一个操作数的运算符,用于一个单独的操作数,并产生一个新值。

var x = 3, y , z;

// 递增(++)
    y = x++;    // y = 3 , x = 4
    z = ++x;    // z = 5 , x = 5

// 递减(--)
    y = x--;    // y = 5 , x = 4
    z = --x;    // z = 3 , x = 3

// 一元负号(-)
    y = -x;    // y = -3 , x = 3

// 一元正号(+)
    +3    // 3
    +"3"    // 3,操作数不是数值的话,会转成一个数值
    +true    // 1
    +function(val){return val}    // NaN

[ 二元算术运算符?↓就是用来处理四则运算(加、减、乘、除)的符号。

// 加法(+)
    1 + 2    // 3

// 减法(-)
    3 - 2    // 1

// 乘法(*)
    2 * 3    // 6

// 除法(/)
    1 / 2    // 在 JavaScript 中返回 0.5

// 求余(%)
    10 % 3    // 1

// 幂(**)
    3 ** 2    // 9

[2] 赋值运算符?↓即把某个常量或变量或表达式的值赋值给另一个变量。

// 赋值
    var y = 10;
    var a = 'demo';

// 加赋值
    y += 2;    // 12    实际是运算过程中的一些缩写,等同于 y = y + 2;    // 12
// 减赋值
    y -= 2;    // 10
// 乘赋值
    y *= 2;    // 20
// 除赋值
    y /= 2;    // 10
// 模赋值
    y %= 3;    // 1

// 解构赋值:将值从数组或将属性值从对象中解构到不同的变量中。

   // 解构数组
      var [a,b,c] = ['one','two','three'];
      console.log(a);    // 'one'
      console.log(b);    // 'two'
      console.log(c);    // 'three'
   // 解构对象
      var {one,tow} = {one:10,two:true};
      console.log(one);    // 10
      console.log(two);    // true

[3] 关系运算符?↓又称为比较运算符,用于比较操作符左右的操作数的大小。

// 大于运算符(>)
    1 > 0    // true

// 大于等于运算符(>=)
    1 >= 1    // true

// 小于运算符(<)
    0 < 1    // true

// 小于等于运算符(<=)
    1 <= 1    // true

[ 相等运算符 ] 主要用于比较操作符左右的操作数是否相等。

// 相等(==)
    1 == 1    // true
    '1' == 1    // true
    0 == false    // true

// 不相等(!=)
    1 != 0    // true
    1 != '1'    // false
    0 != false    // false

// 严格相等(===),同时比较数据类型和值是否相等
    1 === 1    // true
    1 === '1'    // false

// 严格不相等(!==)
    3 !== '3'    // true
    4 !== 3    // true

[4] 位操作符?↓:将其操作数转化为二进制后,进行与、或、非、异或等操作运算,最终返回JS中的一个数值。

var a = 3 , b = 1;        // 转换为二进制    3 = 0 0 1 1
                                           1 = 0 0 0 1
// 按位与(&)
    a & b    // 1                              0 0 0 1    // 都为 1 时
// 按位或(|)
    a | b    // 3                              0 0 1 1
// 按位异或(∧)
    a ∧ b      // 2                            0 0 1 0
// 按位非(~)
   ~a    // -4                                 返回数值的反码,其本质是操作数的负值减 1

// 左移(<<)
   a << 1    // 6                                  0 1 1 0
// 有符号右移动(>>)
   a >> 1    // 1
// 无符号右移(>>>)
   a >>> 1    // 1

[5] 逻辑运算符?↓又叫布尔运算符,主要通过与、或、非来判断一个表达式的值是否为 true。

// 逻辑与(&&)
   result = false && true    // false
   result = false && ( 3 == 4 )    // false && false,结果为false
   result = 'tom' && 'jerry'    // true && true,结果为 jerry

// 逻辑或(||)
   result = false || true    // true
   result = false || ( 3 == 4 )    // false && false,结果为false
   result = 'tom' || 'jerry'    // true && true,结果为 tom

// 逻辑非(!)
    result = !true    // false
    result = !false    // true
    result = !'tom'    // false

// 短路计算:就是说在逻辑计算中,只要一旦能够确定最终结果,就会终止计算
   false & (anything)    // 短路计算的结果为假
   true & (anything)    // 短路计算的结果为真

应用:设置 x 的缺省值
   function test(x){
       x = x || 100;
   }
   test(10);    // 10
   test();    // 100

[6] 其他:条件、逗号、()和void运算符

JS 中运算符总共有46个,除算术运算符、赋值运算符、关系运算符、位运算符、逻辑运算符之外,还有很多运算符。


[6-1] 条件运算符

条件运算符是JS中唯一的一个三元运算符(3个操作数),一般用作if语句的简短形式来使用。

variable = boolean_expression ? true_value : false_value;   // 条件运算符拥有三个操作数,第一个操作数在?之前,第二个在?和:之间,第三个在:之后。

  本质上,这就是基于对boolean_expression求值的结果,决定给变量variable赋什么值。
    如果求值结果是true,则给变量variable赋值true_value;
    如果求值结果是false,则给变量variable赋值false_value。

条件运算符的操作数可以是任意类型,第一个操作数当成布尔值,如果它是真值,那么将计算第二个操作数,并返回其计算结果。
否则,如果第一个操作数是假值,那么将计算第三个操作数,并返回其计算结果。
// 第二个和第三个操作数总是会计算其中之一,不可能两者同时执行。

[ 条件运算符 PK if语句 ]其实使用 if 语句也会带来同样的效果,'?:'运算符只是提供了一种简写形式。

下面是一个'?:'的典型应用场景,判断一个变量是否有定义(并拥有一个有意义的真值),如果有定义则使用它,如果无定义则使用一个默认值:

greeting = 'hello ' + (username ? username : 'there');

这和下面使用if语句的代码是等价的,但显然上面的代码更加简洁:

greeting = 'hello ';
if(username)
    greeting += username;
else
    greeting += 'there';

三元条件表达式与if...else语句具有同样表达效果,但是两者有一个重大差别:if...else是语句,没有返回值;三元条件表达式是表达式,具有返回值。所以,在需要返回值的场合,只能使用三元条件表达式,而不能使用if...else。

console.log(true ? 'T' : 'F');
上面代码中,console.log()方法的参数必须是一个表达式,这时就只能使用三元条件表达式。

[6-2] 逗号运算符

逗号运算符是二元运算符,它的操作数可以是任意类型。它首先计算左操作数,然后计算右操作数,最后返回右操作数的值,用逗号运算符可以在一条语句中执行多个运算。

i = 0,j = 1,k = 2;
//计算结果是2,它和下面的代码基本等价
i =0; j = 1; k = 2;
  • 逗号运算符常用于声明多个变量。
var iNum1 = 1, iNum = 2, iNum3 = 3;

逗号运算符最常用的场景是在for循环中,这个for循环通常具有多个循环变量:
//for循环中的第一个逗号是var语句的一部分
//第二个逗号是逗号运算符
//它将两个表达式(i++和j--)放在一条语句中
for(var i=0, j=10;i<j;i++,j--){console.log(i+j);}
  • 逗号运算符还可以用于赋值,在用于赋值时,逗号运算符总是返回表达式中的最后一项。
var num = (1,2,3,4,5);
console.log(num);//5

[注意]去掉括号会报错

[6-3] 圆括号运算符

圆括号运算符也叫分组运算符,它有两种用法:

  • 如果表达式放在圆括号中,作用是求值;
  • 如果跟在函数后面,作用是调用函数。
把表达式放在圆括号之中,将返回表达式的值。
  console.log((1));   // 1
  console.log(('a'));  // 'a'
  console.log((1+2));  // 3

把对象放在圆括号之中,则会返回对象的值,即对象本身。
  var o = {p:1};
  console.log((o));// Object {p: 1}

将函数放在圆括号中,会返回函数本身。如果圆括号紧跟在函数的后面,就表示调用函数,即对函数求值。
  function f(){return 1;}
  console.log((f));   // function f(){return 1;}
  console.log(f());   // 1

[注意] 圆括号运算符不能为空,否则会报错
  ();   // SyntaxError: Unexpected token )

由于圆括号的作用是求值,如果将语句放在圆括号之中,就会报错,因为语句没有返回值。
  console.log(var a = 1);   // SyntaxError: Unexpected token var
  console.log((var a = 1));   // SyntaxError: Unexpected token var

[6-4] void运算符

void 是一元运算符,它出现在操作数之前,操作数可以是任意类型,操作数会照常计算,但忽略计算结果并返回undefined。由于void会忽略操作数的值,因此在操作数具有副作用的时候使用void来让程序更具语义。

console.log(void 0);  // undefined
console.log(void(0));  // undefined
1. 替代undefined
由于undefined并不是一个关键字,其在IE8-浏览器中会被重写,在高版本函数作用域中也会被重写,所以可以用void 0 来替换undefined。

var undefined = 10;
console.log(undefined);//IE8-浏览器下为10,高版本浏览器下为undefined

function t(){
    var undefined = 10;
    console.log(undefined);
}
console.log(t());   // 所有浏览器下都是10

2. 客户端URL
这个运算符最常用在客户端URL——javascript:URL中,在URL中可以写带有副作用的表达式,而void则让浏览器不必显示这个表达式的计算结果。例如,经常在HTML代码中的a标签里使用void运算符。

<a href="javascript:void window.open();">打开一个新窗口</a>

3. 阻止默认事件:阻止默认事件的方式是给事件置返回值false

// 一般写法
<a href="http://example.com" onclick="f();return false;">文字</a>

使用void运算符可以取代上面写法:
<a href="javascript:void(f())">文字</a>