JavaScript操作符

目录

1 一元操作符

只操作一个值的操作符叫一元操作符。
(1)递增递减操作符
无论使用前缀递增还是前缀递减操作符,变量的值都会在语句被求值之前改变。

let age = 29;
let another = --age+2;

console.log(age); //28
console.log(another); //30

后缀版和前缀版主要区别在于后缀版递增和递减在语句被求值后才发生。

        let num1 = 2;
        let num2 = 20;
        let num3 = num1-- + num2; //22
        let num4 = num1 + num2; //21

递增递减操作符可以用于任何值,意思是不限于整数、字符串、布尔值、浮点值甚至对象都可以,递增递减操作符遵循如下规则:

  • 对于字符串,如果是有效的数值形式,则转换为数值再应用改变。变量类型从字符串变成数值。
  • 对于字符串,如果不是有效的数值形式,则将变量的值设置为NaN。变量类型从字符串变成数值。
  • 对于布尔值,如果是false,则转变为0再应用改变。变量类型从布尔值变成数值。
  • 对于布尔值,如果是true,则转换为1再应用改变。变量类型从布尔值变成数值。
  • 对于浮点值,加1减1。
  • 如果是对象,则调用其valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是NaN,则调用toString()并再次应用其他规则,变量类型从对象变成数值。

(2)一元加和一元减
如果将一元加应用到非数值,则会执行与使用Number()转型函数一样的类型转换:布尔值false和true转换为0和1,字符串根据特殊规则进行解析,对象会调用它们的valueOf()和/或toString()方法以得到可以转换的值。

        let s1 = "01";
        let s2 = "1.1";
        let s3 = "z";
        let b = false;
        let o = {
            valueOf() {
                return -1;
            }
        };

        s1 = +s1; //值变成数值1
        s2 = +s2; //值变成数值1.1
        s3 = +s3; //值变成NaN
        b = +b; //值变成数值0
        f = +f; //不变
        o = +o; //值变成-1

2 布尔操作符

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

  • 如果操作数是对象,则返回false
  • 如果操作数是空字符串,则返回true
  • 如果操作数是非空字符串,则返回false
  • 如果操作数是数值0,则返回true
  • 如果操作数是非0数值,则返回false
  • 如果操作数是null,则返回true
  • 如果操作数是NaN,则返回true
  • 如果操作数是undefined,则返回true

逻辑非操作符也可以用于把任意值转换为布尔值。同时使用两个叹号(!!),相当于调用了转型函数Boolean()。
(2)逻辑与
逻辑与操作符由两个和号(&&)表示,应用到两个值。

第一个操作数 第二个操作数 结果
true true true
true false false
false true false
false false false

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

  • 如果第一个操作数是对象,则返回第二个操作数
  • 如果第二个操作数是对象,则只有第一个操作数求值为true才会返回该对象
  • 如果两个操作数都是对象,则返回第二个操作数。
  • 如果有一个操作数是null,则返回null
  • 如果有一个操作数是NaN,则返回NaN
  • 如果有一个操作数是undefined,则返回undefined

逻辑与操作符是一种短路操作符,意思是如果第一个操作数决定了结果,那么永远不会对第二个操作数求值。对逻辑与操作符来说,如果第一个操作数是false,那么无论第二个操作数是什么值,结果也不可能等于true。
(3)逻辑或
逻辑或操作符由两个管道符(||)表示,遵循如下规则

第一个操作数 第二个操作数 结果
true true true
true false true
false true true
false false false

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

  • 如果第一个操作数是对象,则返回第一个操作数。
  • 如果第一个操作数求值为false,则返回第二个操作数。
  • 如果两个操作数都是对象,则返回第一个操作数。
  • 如果两个操作数都是null,则返回null。
  • 如果两个操作数都是NaN,则返回NaN。
  • 如果两个操作数都是undefined,则返回undefined。

同样与逻辑与类似,逻辑或操作符也具有短路的特性。只不过对逻辑或而言,第一个操作数求值为true,第二个操作数就不会再被求值了。
利用这个行为,可以避免给变量赋值null或undefined:

let myObject = preferredObject || backupObject; 

在这个例子中,变量myObject会被赋予两个值中的一个。其中,preferredObject变量包含首选的值,backupObject变量包含备用的值。

3 乘性操作符

ECMAScript定义了3个乘性操作符:乘法、除法、取模。如果乘性操作符有不是数值的操作数,则该操作数会在后台被使用Number()转型函数转换为数值。
乘法操作符
乘法操作符由一个星号(*)表示,可以用于计算两个数值的乘积。不过乘法操作符在处理特殊值时也有一些特殊的行为:

  • 如果有任意操作数是NaN,则返回NaN
  • 如果是Infinity乘以0,则返回NaN
  • 如果是Infinity乘以非0的有限数值,则根据第二个操作数的符号返回Infinity或-Infinity
  • 如果是Infinity乘以Infinity,则返回Infinity
  • 如果有不是数值的操作数,则先在后台用Number()将其转换为数值,然后再应用上述规则。

除法操作符
除法操作符由一个斜杠(/)表示,用于计算第一个操作数除以第二个操作数的商。跟乘法操作符一样,除法操作符针对特殊值也有一些特殊的行为:

  • 如果有任意操作数是NaN,则返回NaN
  • 如果是0除以0,则返回NaN
  • 如果是非0的有限值除以0,则根据第一个操作数的符号返回Infinity或-Infinity
  • 如果是Infinity除以Infinity,则返回NaN
  • 如果是Infinity除以任何数值,则根据第二个操作数的符号返回Infinity或-Infinity
  • 如果有不是数值的操作数,则先在后台用Number()函数将其转换为数值,然后再应用上述规则。

取模操作符
取模(余数)操作符由一个百分比符号(%)表示,与其他乘性操作符一样,取模操作符对特殊值也有一些特殊的行为:

  • 如果被除数是无限制,除数是有限值,则返回NaN
  • 如果被除数是有限值,除数是0,则返回NaN
  • 如果是Infinity除以Infinity,则返回NaN
  • 如果被除数是有限值,除数是无限值,则返回被除数。
  • 如果被除数是0,除数不是0,则返回0
  • 如果有不是数值的操作数,则先在后台用Number()函数将其转换为数值,然后再应用上述规则。

4 指数操作符

ECMAScript7新增了指数操作符,Math.pow()现在有了自己的操作符**,结果是一样的。

        console.log(Math.pow(3, 2)); //9
        console.log(3 ** 2); //9

5 加性操作符

(1)加性操作符(+)用于求两个数的和,如果两个操作数都是数值,加法操作符执行加法运算并根据如下规则返回结果:

  • 如果有任意操作数是NaN,则返回NaN
  • 如果是Infinity加Infinity,则返回Infinity
  • 如果是-Infinity加-Infinity,则返回-Infinity
  • 如果是Infinity加-Infinity,则返回NaN
  • 如果是+0加+0,则返回+0
  • 如果是-0加+0,则返回+0
  • 如果是-0加-0,则返回-0

如果有一个操作数是字符串,则要应用如下规则:

  • 如果两个操作数都是字符串,则将第二个字符串拼接到第一个字符串后面
  • 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,再将两个字符串拼接在一起。

如果有任意操作数是对象、数值或布尔值,则调用他们的toString()方法以获取字符串,然后再应用前面的关于字符串规则。对于undefined和null,则调用String()函数,分别获取"undefined"和"null"。

        let result1 = 5+5;
        console.log(result1); //10

        let result2 = 5+"5";
        console.log(result2);//"55"

(2)减法操作符
减法操作符(-)也是使用很频繁的一种操作符,与加法操作符一样,减法操作符也有一组规则用于处理ECMAScript中不同类型之间的转换:

  • 如果有任意操作数是NaN,则返回NaN
  • 如果是Infinity减Infinity,则返回NaN
  • 如果是-Infinity减-Infinity,则返回NaN
  • 如果是Infinity减-Infinity,则返回Infinity
  • 如果是-Infinity减Infinity,则返回-Infinity
  • 如果是+0减+0,则返回+0
  • 如果是+0减-0,则返回-0
  • 如果是-0减-0,则返回+0
  • 如果有任意操作数是字符串,布尔值,null或undefined,则先在后台使用Number()将其转换为数值,然后再根据前面的规则执行数学运算。
  • 如果有任意操作数是对象,则调用其valueOf()方法取得表示它的数值。如果该值是NaN,则减去计算的结果NaN,如果对象没有valueOf()方法,则调用其toString()方法,然后再将得到的字符串转换为数值。

6 关系操作符

关系操作符执行比较两个值的操作,包括小于(<)、大于(>)、小于等于(<=)和大于等于(>=),这几个操作符都返回布尔值。
与ECMAScript中的其他操作符一样,在将它们应用到不同数据类型时也会发生类型转换和其他行为。

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

对字符串而言,关系操作符会比较字符串中对应字符的编码,而这些编码是数值。比较完之后,会返回布尔值。大写字母的编码都是小于小写字母的编码,因此以下这种情况就会发生:

let result = "Brick"<"alphabet"; //true

在这里字符串"Brick"被认为小于字符串"alphabet",因为字母B的编码是66,字母a的编码是97。要得到确实按照字母顺序比较的结果,就必须把两者都转换为相同的大小写形式(全大写或全小写)然后再比较:

let result = "Brick".toLowerCase<"alphabet".toLowerCase; //false

另一个比较奇怪的现象是在比较两个数值字符串的时候,如:

let result = "23"<"3"; //true

这里在比较字符串"23"和"3"时返回true。因为两个操作数都是字符串,所以会逐个比较它的字符编码(字符"2"的编码是50,而字符"3"的编码是51)。不过如果有一个操作数是数值,那么比较结果就对了:

let result = "23"<3; //false

只要数值和字符串比较,字符串就会先被转换为数值,然后再进行数值比较,对于数值字符串而言,这样能保证结果的正确,而如果字符串不能转换为数值呢?

let result = "a"<3;

因为"a"不能转换为任何有意义的值,所以只能转换为NaN,这里有个规则,即任何关系操作符在涉及比较NaN时都返回false:

        let result1 = NaN<3; //false
        let result2 = NaN>=3; //false

7 相等操作符

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

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

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

  • null和undefined相等
  • null和undefined不能转换为其他类型的值再进行比较。
  • 如果任意操作数是NaN,则相等操作符返回false,不相等操作符返回true。
  • 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true。否则,两者不相等。

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

let result1 = ("55"==55); //true
let result2 = ("55"===55); //false

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

8 条件操作符

variable = boolean_expression?true_value:false_value;

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

9 赋值操作符

10 逗号操作符

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

let num1 = 1,num2 = 2,num3 = 3;
上一篇:Ubantu下安装FTP服务器


下一篇:python – 如何实现Inf和NaN?