JS基础--运算符及其优先级

979 阅读6分钟

运算符及其优先级

运算符

算数运算符

算数运算符主要用于数学运算或是字符串拼接。

  1. number类型的运算

    • 加减乘除,+ - * /

    • 取余:1 % 7 = 1

      • JS负数取余: -1 % 7 是 -(1 % 7)= -1,而正常来说 -1 % 7 = (-1+7)%7=6 这是JS的一个bug。
    • 指数:2**3 = 8

    • 自增自减1:x++/++x/x--/--x

      x++(x--)与++x(--x)的区别

      // x++(x--) 的值是 x
      // ++x(--x) 的值是 x+1(x-1)
      let a = 1
      let b = a++
      b // 1
      a // 2
      
    • 求值运算符:+

      let a = 8
      let b = -8
      +a // 8
      +b // -8
      
    • 负数运算符:-

      -(-8) // 8

  2. String运算

    String只有一种运算就是拼接,拼接运算符是+

    'abc' + 'def' // 'abcdef'
    
  3. 算数运算符的使用技巧

    • 减少使用“自增自减”,除了在for循环中,其它地方一律使用a+=1 or a-=1代替自增自减。

    • 避免两个不同类型进行运算,除了数据类型转换

      Number+String:转换成字符串后拼接;

      Number-String:转换成数字类型后相减

比较运算符

> < >= <= == != === !==

  1. ==的弊端

  • JS的 ==的true/false判定非常复杂,建议永远不要使用==而是使用===进行判断。
  1. ===的特点

    • 判断基本类型根据值是否相等
    • 判断对象看地址是否相等,[] === [] // false地址不同
    • 1个特殊的判断 NaN !== NaN // true

布尔运算符

  1. 布尔运算符的3个类型

    1. || :从左到右执行表达式或语句,根据表达式的值和语句的返回值转换成布尔值的true/false,取第一个转换布尔值为true的表达式的值或返回值。

      // 短路逻辑
      a = b || 100 // 给a赋予一个保底的100
      

      a || 0 下,想把一个值为falsy值的 a 赋予参数或变量作为保底值并不能实现。所以在函数中使用时,最好直接给参数赋值 function fn(a = 1) 来作为保底值,替代这个语法。

    2. &&:从左到右执行表达式或语句,根据表达式的值和语句的返回值转换成布尔值的true/false,取第一个转换布尔值为false的表达式的值或返回值。

      // 短路逻辑
      console && console.log && console.log('hi')
      // 防止没有console 或 console.log 的环境下执行console.log() 报错
      
    3. :取表达式的值或语句的返回值转换成布尔值后的相反值。

      let a = 1
      !a // flase
      !(console.log('hi')) // true 因为 console.log('hi') 返回undefined是falsy值
      

二进制运算符

“二进制运算符”又称“位运算符”,因为这些运算结果都是2个二进制每个位之间对比结果得来。位运算符只进行整数部分的运算,小数部分在运算前便自动忽略。

  1. 类型

    • |:2个二进制数,对应数位都为0,则结果为0,否则为1。

      (0b1001 | 0b1100).toString(2) // 1101

    • &:2个二进制数,对应数位都为1,则结果为1,否则为0。

      (0b1001 & 0b1100).toString(2) // 1000

    • ~:比较复杂,涉及到反码、补码。简单记忆:十进制下,~(A) = -(A+1)。

    • 异或^:2个二进制数,对应数位相同,则结果为0,否则为1。

      (0b1001 ^ 0b1100).toString(2) // 0101

    • 左移<<、右移>>:二进制数整体像左右移动 n 位,右移时右边第一位直接不见。

      (0b1001>>1).toString(2) // 100  最右边的1不见了
      (0b1001<<1).toString(2) // 10010 
      
    • 头部补0的右移>>>:作用和右移运算符没太大区别。

  2. 位运算符的妙用

    • &运算符判断奇偶

      偶数 & 1 // 0 falsy
      奇数 & 1 // 1 true
      
    • ~ ,>>,<<,>>>,|来取整,位运算符运算器忽略小数部分。

      console.log(~~ 6.83) //6
      console.log(6.83>>0) //6
      console.log(6.83>>>0) //6
      console.log(6.83<<0) //6
      console.log(6.83|0) //6 一个数和0,位或运算是其本身。
      
    • 2变量值互换

      let a = 5
      let b = 8
      a ^= b // a ^= b 即 a = a ^ b
      b ^= a 
      a ^= b
      a // 8
      b // 5
      

      但是我们一般使用[b,a] = [a,b]来实现这个效果。

点运算符

  • 点运算符就是我们常用的点语法中的那个“点”,用于读取对象的属性。

  • 点运算符前面的一定是一个对象,为什么数字、字符串、布尔值这些非对象类型也能使用点语法?因为如果点运算符前面的数据不是对象则会自动转换成一个临时的对象,并调用该临时对象原型的方法,完成运算后删除临时对象。

    let a = 'a-b-c'
    a.split('-') // ['a','b','c']
    a.name = 'jack'
    console.log(a.name) // undefined 临时对象被删除了
    
  • 数据自动转换:number=>Number对象、string=>String对象、bool=>Boolean对象;但是实际开发中,从来不会使用这三种对象。

void运算符

  • 语法:void 表达式或语句。先执行表达式或语句,然后再执行void。
  • void语句的值永远是undefined。
  • 用法1:<a href="javascript:void(document.form.submit());">点击提交表单但是不跳转</a>
  • 用法2:<a href="javascript:void(0);">1+2</a>一个没有任何动作的<a>

逗号运算符

  • 语法:表达式1(语句1),表达式2(语句n),...,表达式n(语句n)

  • 注意:使用逗号运算符一般要使用()将整体包裹起来,看成一个整体。如果不用JS断句可能会出现问题。

  • 效果:将整个表达式或语句串作为整体,表达式n(语句n)的值作为整体的值。

    let a = (1+2,3+5,8+5)
    a // 13
    
  • 配合箭头函数:

    // 正常情况下,{}中有2句以上的语句,不能省略{}与return
    let fn = (x) =>{
        console.log('hello')
    	return x*x
    }
    // 使用逗号改写
    // (console.log('hello'),x*x) 就可以看成一个整体变成1句语句了,这句语句的值就是 x*x
    let fn1 = x =>(console.log('hello'),x*x)
    

运算符优先级

JS运算符的优先级非常复杂,不需要详细看,只需要记忆几个重点:

  1. 加减乘除:先乘除后加减。

  2. 除了'='相同的运算符运算顺序均为左到右。

  3. =赋值符运算顺序为右到左。

    let a,b,c,d
    a = b = c = d = 2 // d=2 => c=d => b=c => a=b
    // 实际上是这样的
    (a=(b=(c=(d=2))))
    
  4. ()运算符优先级最高!!! 想先算什么就给那部分套个括号就完事了。