【零基础JavaScript初阶】操作符

ECMA-262描述了一组可用于操作数据值的操作符,包括数学操作符(如加、减)、位操作符、关系操作符和相等操作符等。ECMAScript中的操作符是独特的,因为它们可用于各种值,包括字符串、数值、布尔值,甚至还有对象。

1.1一元操作符

只操作一个值的操作符叫一元操作符。

1.1.1递增/递减操作符

递增和递减操作符直接照搬自C语言,但有两个版本:前缀版后缀版。顾名思义,前缀版就是位于要操作的变量前头,后缀版就是位于要操作的变量后头。前缀递增操作符会给数值加1,把两个加号(++)放到变量前头即可:

    let age = 29;
    ++age;

上面的例子实际上等于如下表达式:

    let age = 29;
    age=age+1;

前缀递减操作符也类似,只不过是从一个数值减1。使用前缀递减操作符,只要把两个减号(--)放到变量前头即可:

    let age = 29;
    --age;

无论使用前缀递增还是前缀递减操作符,变量的值都会在语句被求值之前改变。(在计算机科学中,这通常被称为具有副作用。)请看下面的例子:

    let age = 29;
    let anotherAge = --age + 2;
    console.log(age);           // 28
    console.log(anotherAge);   // 30

在这个例子中,变量anotherAge以age减1后的值再加2进行初始化。因为递减操作先发生,所以age的值先变成28,然后再加2,结果是30。

注意:在前缀递增或递减中,递增或递减操作先先发生,再进行语句求值。

递增和递减的后缀版语法一样(分别是++和--),只不过要放在变量后面。后缀版与前缀版的主要区别在于,后缀版递增和递减在语句被求值后才发生

    let num1 = 2;
    let num2 = 20;
    let num3= num1-- + num2;
    let num4 = num1 + num2;
    console.log(num3);   // 22
    console.log(num4);   // 21

注意:后缀版递增和递减在语句被求值后才发生。

这4个操作符可以作用于任何值,意思是不限于整数——字符串、布尔值、浮点值,甚至对象都可以。

1.2布尔操作符

布尔操作符一共有3个:逻辑非逻辑与逻辑或

1.2.1逻辑非

逻辑非操作符由一个叹号(!)表示,可应用给ECMAScript中的任何值。这个操作符始终返回布尔值,无论应用到的是什么数据类型。逻辑非操作符首先将操作数转换为布尔值,然后再对其取反。换句话说,逻辑非操作符会遵循如下规则。

操作数返回值
对象false
字符串空字符串,返回true非空字符串,返回false
数值数值0,返回true非0数值,返回false
nulltrue
NANtrue
undefinedtrue

 以下示例验证了上述行为:

    console.log(! false);    // true
    console.log(! "blue");   // false
    console.log(!0);         // true
    console.log(! NaN);      // true
    console.log(! "");        // true
    console.log(!12345);    // false

逻辑非操作符也可以用于把任意值转换为布尔值。同时使用两个叹号(! !),相当于调用了转型函数Boolean()。无论操作数是什么类型,第一个叹号总会返回布尔值。第二个叹号对该布尔值取反,从而给出变量真正对应的布尔值。结果与对同一个值使用Boolean()函数是一样的:

    console.log(! ! "blue"); // true
    console.log(! !0);        // false
    console.log(! ! NaN);     // false
    console.log(! ! "");      // false
    console.log(! !12345);   // true

 1.2.2逻辑与

逻辑与操作符由两个和号(&&)表示,应用到两个值,如下所示:

    let result = true && false;

逻辑与操作符遵循如下真值表:

 逻辑与操作符可用于任何类型的操作数,不限于布尔值。如果有操作数不是布尔值,则逻辑与并不一定会返回布尔值,而是遵循如下规则。

操作数返回值
第一个操作数是对象返回第二个操作数
第二个操作数是对象当第一个操作数求值为true才会返回该对象
两个操作数都是对象返回第二个操作数
nullnull
NANNAN
undefinedundefined

 逻辑与操作符是一种短路操作符,意思就是如果第一个操作数决定了结果,那么永远不会对第二个操作数求值对逻辑与操作符来说,如果第一个操作数是false,那么无论第二个操作数是什么值,结果也不可能等于true。看下面的例子:

    let found = true;
    let result = (found && someUndeclaredVariable); // 这里会出错
    console.log(result); // 不会执行这一行

上面的代码之所以会出错,是因为someUndeclaredVariable没有事先声明,所以当逻辑与操作符对它求值时就会报错。变量found的值是true,逻辑与操作符会继续求值变量someUndeclaredVariable。但是由于someUndeclaredVariable没有定义,不能对它应用逻辑与操作符,因此就报错了。假如变量found的值是false,那么就不会报错了:\

    let found=false;
    let result = (found && someUndeclaredVariable);   // 不会出错
    console.log(result);   // 会执行

这里,console.log会成功执行。即使变量someUndeclaredVariable没有定义,由于第一个操作数是false,逻辑与操作符也不会对它求值,因为此时对&&右边的操作数求值是没有意义的。在使用逻辑与操作符时,一定别忘了它的这个短路的特性。

1.2.3逻辑或

逻辑或操作符由两个管道符(||)表示,比如:

   let result = true || false;

逻辑或操作符遵循如下真值表:

 与逻辑与类似,如果有一个操作数不是布尔值,那么逻辑或操作符也不一定返回布尔值。它遵循如下规则。

操作数返回值
第一个操作数是对象返回第一个操作数
第一个操作数求值为false返回第二个操作数
两个操作数都是对象返回第一个操作数
nullnull
NANNAN
undefinedundefined

 

同样与逻辑与类似,逻辑或操作符也具有短路的特性。只不过对逻辑或而言,第一个操作数求值为true,第二个操作数就不会再被求值了。看下面的例子:

    let found = true;
    let result = (found || someUndeclaredVariable); // 不会出错
    console.log(result); // 会执行

跟前面的例子一样,变量someUndeclaredVariable也没有定义。但是,因为变量found的值为true,所以逻辑或操作符不会对变量someUndeclaredVariable求值,而直接返回true。假如把found的值改为false,那就会报错了:

    let found=false;
    let result = (found || someUndeclaredVariable); // 这里会出错
    console.log(result); // 不会执行这一行

利用这个行为,可以避免给变量赋值null或undefined。比如

    let myObject = preferredObject || backupObject;

在这个例子中,变量myObject会被赋予两个值中的一个。其中,preferredObject变量包含首选的值,backupObject变量包含备用的值。如果preferredObject不是null,则它的值就会赋给myObject;如果preferredObject是null,则backupObject的值就会赋给myObject。这种模式在ECMAScript代码中经常用于变量赋值.

1.3关系操作符

关系操作符执行比较两个值的操作,包括小于(<)、大于(>)、小于等于(<=)和大于等于(>=),用法跟数学课上学的一样。这几个操作符都返回布尔值,如下所示:

    let result1 = 5 > 3; // true
    let result2 = 5 < 3; // false

与ECMAScript中的其他操作符一样,在将它们应用到不同数据类型时也会发生类型转换和其他行为。

  • 如果操作数都是数值,则执行数值比较。
  • 如果操作数都是字符串,则逐个比较字符串中对应字符的编码
  • 如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较。
  • 如果有任一操作数是对象,则调用其valueOf()方法,取得结果后再根据前面的规则执行比较。如果没有valueOf()操作符,则调用toString()方法,取得结果后再根据前面的规则执行比较。
  • 如果有任一操作数是布尔值,则将其转换为数值再执行比较。

在大多数比较的场景中,如果一个值不小于另一个值,那就一定大于或等于它。但在比较NaN时,无论是小于还是大于等于,比较的结果都会返回false。

1.4相等操作符

在比较字符串、数值和布尔值是否相等时,过程都很直观。但是在比较两个对象是否相等时,情形就比较复杂了。ECMAScript中的相等和不相等操作符,原本在比较之前会执行类型转换,但很快就有人质疑这种转换是否应该发生。最终,ECMAScript提供了两组操作符。

  1. 第一组是等于和不等于,它们在比较之前执行转换
  2. 第二组是全等和不全等,它们在比较之前不执行转换

1.4.1等于和不等于

ECMAScript中的等于操作符用两个等于号(==)表示,如果操作数相等,则会返回true。不等于操作符用叹号和等于号(! =)表示,如果两个操作数不相等,则会返回true。这两个操作符都会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等。

在转换操作数的类型时,相等和不相等操作符遵循如下规则:

操作数转换规则
如果任一操作数是布尔值将布尔值转换为数值再比较是否相等。false转换为0,true转换为1。
如果一个操作数是字符串,另一个操作数是数值将字符串转换为数值,再比较是否相等。
如果一个操作数是对象,另一个操作数不是调用对象的value()方法取得其原始值,再根据前面的规则进行比较。

在进行比较时,这两个操作符会遵循如下规则:

  • null和undefined相等。
  • null和undefined不能转换为其他类型的值再进行比较。
  • 如果有任一操作数是NaN,则相等操作符返回false,不相等操作符返回true。记住:即使两个操作数都是NaN,相等操作符也返回false,因为按照规则,NaN不等于NaN。
  • 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true。否则,两者不相等。

1.4.2全等和不全等

全等和不全等操作符与相等和不相等操作符类似,只不过它们在比较相等时不转换操作数。全等操作符由3个等于号(===)表示,只有两个操作数在不转换的前提下相等才返回true,比如:

    let result1 = ("55" == 55);    // true,转换后相等
    let result2 = ("55" === 55);   // false,不相等,因为数据类型不同

不全等操作符用一个叹号和两个等于号(! ==)表示,只有两个操作数在不转换的前提下不相等才返回true。比如:

    let result1 = ("55" ! = 55);   // false,转换后相等
    let result2 = ("55" ! == 55); // true,不相等,因为数据类型不同

注意: 由于相等和不相等操作符存在类型转换问题,因此推荐使用全等和不全等操作符。这样有助于在代码中保持数据类型的完整性。

1.5条件操作符

条件操作符是ECMAScript中用途最为广泛的操作符之一,语法跟Java中一样:

   variable = boolean_expression ? true_value : false_value;

上面的代码执行了条件赋值操作,即根据条件表达式boolean_expression的值决定将哪个值赋给变量variable。如果boolean_expression是true,则赋值true_value;如果boolean_expression是false,则赋值false_value。

1.6逗号操作符

逗号操作符可以用来在一条语句中执行多个操作,如下所示:

    let num1 = 1, num2 = 2, num3 = 3;

在一条语句中同时声明多个变量是逗号操作符最常用的场景。不过,也可以使用逗号操作符来辅助赋值。在赋值时使用逗号操作符分隔值,最终会返回表达式中最后一个值:

  let num = (5, 1, 4, 8, 0); // num的值为0

在这个例子中,num将被赋值为0,因为0是表达式中最后一项。逗号操作符的这种使用场景并不多见,但这种行为的确存在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值