02. JavaScript基础——操作符

一元操作符

  1. 定义:只操作一个值的操作符

递增/递减操作符

  1. 前缀版

    1. 位于要操作的变量前面

    2. 变量的值会在语句被求值之前改变

    3. 前缀递增和前缀递减的优先级相等,所有从左向右依次求值

    4. 前缀递增操作符会给数值加1

      let a = 20;
      ++a;
      // 上述代码等效于下面的代码
      let a = 20;
      a = a+1;
      
    5. 前缀递减操作符给数值减1

      let a = 20;
      --a;
      // 上述代码等效于下面的代码
      let a = 20;
      a = a-1;
      
  2. 后缀版

    1. 位于要操作的变量后面

    2. 后缀版操作符在语句被求值之后才生效

    3. 例子

      let n1 = 2;
      let n2 = 20;
      let n3 = n1-- + n2;
      let n4 = n1 + n2;
      
      console.log(n3); // n3的值是22,因为这里n3使用的是n1的原始值再加上n2
      console.log(n4);  // n4的值是21,因为这里的n1在上面计算n3的时候被减1了
      
  3. 这四个操作符可以作用于任何值

    • 布尔值
      • 如果是false,转成0再改变。此时变量类型变成数字
      • 如果是true,转成1再改变。此时变量类型变成数字
    • 浮点值
      • 直接加1或减1
    • 对象
      • 调用其valueOf()方法取得可以操作的值
      • 对这个可以操作的值应用上述规则
      • 如果是NaN就调用toString()并应用上述规则
      • 变量类型从对象变成数字
    • 字符串
      • 如果是有效的数值形式,转成数字再改变。此时变量类型从字符串变成数字
      • 如果不是有效的数值形式,就将变量的值设置为NaN。此时变量类型从字符串变成数字
  4. 例子

    let str1 = "2";
    let str2 = "a";
    let f = false;
    let a = 1.1;
    let obj = {
        valueOf(){
            return -1;
        }
    };
    
    console.log(++str1);  // 3
    console.log(str1++);  // 2
    
    console.log(str2++);  // NaN
    console.log(++str2); // NaN
    
    console.log(f++); // 0
    console.log(++f); // 1
    
    console.log(a++);  // 1.1
    console.log(++a); // 2.1
    
    console.log(obj--); // -1
    console.log(++obj); // 0
    

一元加和减

  1. 数学上的加法和减法
  2. 如果应用到非数值上,
    1. 布尔值:false转成0,true转成1
    2. 字符串:根据特殊规则进行解析
    3. 对象:调用valueOf()方法,toString()方法

位操作符

  1. 主要用于操作内存中表示数据的比特(位)
  2. 有符号整数使用32位表示,其中前31位表示整数值,第32位是符号位(即从左数第一位是符号位),表示符号(0表示正,1表示负)
    1. 正值以真正的二进制格式存储,即31位中每一位都表示2的幂,从右向左数,第一位是2的零次方,第二位是2的一次方,以此类推,如果一个位是空的,就以0填充,表示忽略不计
    2. 负值以一种称为二补数(补码)的二进制编码存储,补码计算步骤如下:
      • 确定其绝对值的二进制表示(比如对于-13,先确定13的二进制)
      • 找到每一位数字的一补数(反码),即每个0都变成1,每个1都变成0
      • 给每一个反码都加上1

按位非

  1. 按位非操作符使用波浪符(~)表示

  2. 按位非的作用是返回数字的一补数(反码)

  3. 最终效果是对数字取反然后减1

  4. 例子

    let n1 = 23;
    let n2 = ~n1;
    
    console.log(n1.toString(2));  // 二进制是10111
    console.log(n2.toString(2)); // 二进制是-11000
    console.log(n2);  // -24
    

按位与

  1. 按位与操作符使用和号(&)表示

  2. 有两个操作数,将两个操作数的每一位对齐,然后按照指定的规则对每一位进行相应的操作

  3. 规则

    第一个数字的位 第二个数字的位 结果
    1 1 1
    1 0 0
    0 1 0
    0 0 0
  4. 总的来说就是:全1得1,有0得0

  5. 例子

    let n1 = 25;
    let n2 = 3;
    
    console.log(n1.toString(2));  // 25的二进制是11001
    console.log(n2.toString(2));  // 3的二进制是11
    
    console.log(n1&n2);  // 结果是1
    
    • 可以看出,25和3的二进制表示中,只有第0位上两个数都是1,其他都是0

按位或

  1. 按位或操作符用管道符(|)表示

  2. 有两个操作数,将两个操作数的每一位对齐,然后按照指定的规则对每一位进行相应的操作

  3. 规则

    第一个数字的位 第二个数字的位 结果
    1 1 1
    1 0 1
    0 1 1
    0 0 0
  4. 总的来说就是:有1得1,全0得0

  5. 例子

    let n1 = 25;
    let n2 = 3;
    
    console.log(n1.toString(2));  // 25的二进制是11001
    console.log(n2.toString(2));  // 3的二进制是11
    
    console.log(n1|n2);  // 结果是27
    
    • 将25和3的二进制表示对齐之后,得到的二进制结果是11011,转成十进制就是27

按位异或

  1. 按位异或用脱字符(^)表示

  2. 有两个操作数,将两个操作数的每一位对齐,然后按照指定的规则对每一位进行相应的操作

  3. 规则

    第一个数字的位 第二个数字的位 第二个数字的位
    1 1 0
    1 0 1
    0 1 1
    0 0 0
  4. 总的来说就是:相同得0,不同得1

  5. 例子

    let n1 = 25;
    let n2 = 3;
    
    console.log(n1.toString(2));  // 25的二进制是11001
    console.log(n2.toString(2));  // 3的二进制是11
    
    console.log(n1^n2);  // 结果是26
    

    将25和3的二进制表示对齐之后,按照规则得到的二进制结果是11010,转成十进制就是26

左移

  1. 左移操作符使用两个小于号表示

  2. 会按照指定的位数将数字的所有位向左移动

  3. 移动之后,数字右端会空出位数,然后以0填充这些空位

  4. 左移会保留它所操作数值的符号

  5. 例子

    let n1 = 2;
    let n2 = n1 << 5;
    
    console.log(n2.toString(2));  // 二进制表示结果是:1000000
    console.log(n2);  // 转成十进制就是64
    

有符号右移

  1. 有符号右移使用两个大于号表示,会将数字的所有32位往右边移动,同时保留符号
  2. 右移之后会出现空位,但是空位出现在左侧,而且在符号位之后,会使用符号位的值来填充这些空位

无符号右移

  1. 无符号右移使用三个大于号表示,会将数字的所有32位向右移
  2. 对于正数,无符号右移和有符号右移结果一样
  3. 对于负数,无符号右移会给空位补0,不考虑符号位
  4. 此时会将负数的二进制表示当成正数的二进制表示来处理

布尔操作符

逻辑非

  1. 逻辑非操作符使用感叹号表示,无论应用到什么数据类型,都是先将操作数转成布尔值,然后取反
  2. 规则
    • 操作数是对象,返回false
    • 操作数是空字符串,返回true
    • 操作数是非空字符串,返回false
    • 操作数是0,返回true
    • 操作数是非0数字(包括Infinity),返回false
    • 操作数是null,返回true
    • 操作数是NaN,返回true
    • 操作数是undefined,返回true
  3. 同时使用两个感叹号,也可以将任意值转成布尔值,第一个感叹号会将操作数转成布尔值,第二个感叹号对这个布尔值取反,从而得出操作数真正对应的布尔值

逻辑与

  1. 逻辑与操作符用两个和号(&&)表示
  2. 对两个操作数进行操作
  3. 规则:两个都是true就返回true,有一个是false就返回false
  4. 逻辑与是一种短路操作符,即如果第一个操作数决定了结果,那么永远不会对第二个操作数求值
  5. 可以应用于任何类型的操作数,如果有操作数不是布尔值,那么会遵循一定的规则
    • 如果第一个操作数是对象,那么返回第二个操作数
    • 如果第二个操作数是对象,那么只有第一个操作数求值为true才会返回该对象
    • 如果两个操作数都是对象,返回第二个操作数
    • 如果有一个操作数是null,返回null
    • 如果有一个操作数是NaN,返回NaN
    • 如果有一个操作数是undefined,返回undefined

逻辑或

  1. 逻辑或操作符用两个管道号(||)表示
  2. 规则:两个都是false就返回false,有一个是true就返回true
  3. 逻辑或是一种短路操作符,如果第一操作数求值是true,第二个操作数就不会被求值了
  4. 可以应用于任何类型的操作数,如果有操作数不是布尔值,那么会遵循一定的规则
    • 如果第一个操作数是对象,那么返回第一个操作数
    • 如果第一个操作数求值是false,那么返回第二个操作数
    • 如果两个操作数都是对象,返回第一个操作数
    • 如果两个操作数都是null,返回null
    • 如果两个操作数都是NaN,返回NaN
    • 如果两个操作数都是undefined,返回undefined

乘性操作符

乘法操作符

  1. 星号表示乘法操作符,计算乘积
  2. 特殊规则
    • 如果操作数都是数字,执行常规的乘法运算,如果不能表示乘积,就返回Infinity或-Infinity
    • 任意一个操作数是NaN,返回NaN
    • Infinity乘以0,返回NaN
    • Infinity乘以非0的有限数值,根据第二个操作数的返回确定返回Infinity或-Infinity
    • 如果是Infinity乘以Infinity,返回Infinity
    • 如果有不是数值的操作符,那么先在后台使用Number()将其转换为数字,再应用上述规则

除法操作符

  1. 一个斜杠表示触发操作符
  2. 特殊规则
    • 如果操作数都是数字,执行常规的除法运算,如果不能表示商,就返回Infinity或-Infinity
    • 任意一个操作数是NaN,返回NaN
    • Infinity除以Infinity,返回NaN
    • 0除以0,返回NaN
    • 非0的有限值除以0,根据第一个操作数的符号返回Infinity或-Infinity
    • Infinity除以任何数值,根据第二个操作数的符号返回Infinity或-Infinity
    • 如果有不是数值的操作符,那么先在后台使用Number()将其转换为数字,再应用上述规则

取模操作符

  1. 一个百分比符号表示取模操作符
  2. 特殊规则
    • 如果操作数都是数字,执行常规的除法运算,返回余数
    • 如果被除数是无限值,除数是有限值,返回NaN
    • 如果被除数是无限值,除数0,返回NaN
    • Infinity除以Infinity,返回NaN
    • 如果被除数是有限值,除数无限值,返回被除数
    • 如果被除数是0,除数不是0,返回0
    • 如果有不是数值的操作符,那么先在后台使用Number()将其转换为数字,再应用上述规则

指数操作符

  1. 两个乘号表示指数操作符

  2. 效果和Math.pow()一样

  3. 例子

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

加性操作符

加法操作符

  1. 使用加号表示
  2. 特殊规则
    • 任一操作数是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

减法操作符

  1. 使用减号表示
  2. 特殊规则
    • 任一操作数是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()转成数值,然后根据规则进行计算,如果转换的结果是NaN,那么减法结果是NaN
    • 如果任一操作数是对象,则调用其valueOf()方法取得它的数值
      • 如果这个值是NaN,则减法结果是NaN
      • 如果对象没有valueOf()方法,那么调用toString()方法,将得到的字符串转成数字

关系操作符

  1. 用来比较两个值的操作,包括小于,大于,小于等于,大于等于,都返回布尔值
  2. 特殊规则
    • 如果操作数都是数字,执行数字比较
    • 如果操作数是字符串,则逐个比较字符串中对应字符串的编码
    • 如果任一操作数是数字,则将另一个操作数转成数字,执行数字比较
    • 如果任一操作数是对象
      • 调用其valueOf()方法,取得结果后再根据前面的规则执行比较
      • 如果没有valueOf()方法,调用toString()方法,取得结果后再根据前面的规则执行比较
    • 如果任一操作数是布尔值,转成数字再比较
    • 任何关系操作符在涉及到NaN的比较时,都返回false

相等操作符

等于和不等于

  1. 使用两个等于号表示等于操作符
  2. 使用感叹号和等于号表示不等于操作符
  3. 这两个操作符在比较之前会先进行类型转换(强制类型转换)
  4. 转换类型的规则
    • 如果任何一个操作数是布尔值,则将它转成数字之后再和另一个操作数比较(false转成0,true转成1)
    • 如果一个操作数是字符串,另一个是数字,那么就尝试将字符串转成数字再比较
    • 如果一个操作数是对象,另一个不是,就调用对象的valueOf()方法取其原始值,然后再根据前面的规则比较
  5. 比较规则
    • null和undefined相等
    • null和undefined不能转换成其他类型的值
    • 如果有任何一个操作数是NaN,则相等操作符返回false,不相等操作符返回true(就算两个都是NaN也是这个结果)
    • 如果两个操作数都是对象,那么就比较它们是不是同一个对象,如果它们两个都指向同一个对象,相等操作符返回true

全等和不全等

  1. 全等操作符

    1. 三个等号表示

    2. 只有两个操作数在不转换的情况下相等才返回true

      let result1 = ("55"==55); // true,等于操作符先转换,转换之后比较是相等的
      
      let result2 = ("55"===55); // false,全等操作符不能转换,比较是不相等的
      
  2. 不全等操作符

    1. 用一个叹号和两个等于号表示

    2. 只有两个操作数在不转换的情况下不相等才返回true

      let result1 = ("55"!=55); // false,不等于操作符先转换,转换之后比较是相等的
      
      let result2 = ("55"!==55); // true,不全等操作符不能转换,比较是不相等的
      
    3. 注意:null==undefined的结果是true,但是null===undefined的结果是false,因为它们类型不同

条件操作符

  1. 语法格式

    1. 变量名 = 判断表达式 ? 表达式成立的赋值 : 表达式不成立的赋值;

    2. 例子

      v1 = (n1 > n2) ? n1:n2; // 这里表示如果n1大于n2,就把n1的值赋给v1,否则就把n2的值赋给v1
      

赋值操作符

  1. 简单赋值

    1. 使用等号,将右边的值赋给左边的变量
  2. 复合赋值

    1. 使用乘性,加性或位操作符和等号结合

      let n1 = 10;
      n1 += 10;
      

逗号操作符

  1. 可以在一条语句中执行多个操作

    let n1 = 1,n2 = 2,n3 = 3;
    
  2. 可以在一条语句中同时声明多个变量

    let num1 = (5,4,1,0); // 最后num1的值是0,因为0是表达式中最后一项
    

你可能感兴趣的:(02. JavaScript基础——操作符)