• JavaScript基本概念——操作符


    Get busy living,or get busy dying.

    JavaScript操作符

    ECMAScript 操作符与众不同之处在于,它能适用于对象,此时操作符通常会调用对象的 valueOf() 或 toString() 方法以取得可以操作的值。

    一元操作符

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

    1. 递增和递减操作符

    借鉴自 C 语言,前置型会在语句运行时被执行,后置型会在语句结束后执行。
    在应用于不同的值时,递增递减操作符遵循以下规则:

    • 应用于包含有效数字的字符串,先转换为数字,再执行加减操作,字符串变量变成数值变量
    • 应用于不包含有效数字的字符串,将变量的值设置为 NaN,字符串变量变成数值变量(NaN 是特殊的数值类型)
    • 应用于布尔值,先转换为数字 0 或 1,再执行加减操作,布尔值变量变成数值变量
    • 应用于浮点数值,执行加减操作
    • 应用于对象,先调用对象的 valueOf() 方法取得可操作的值,然后应用上述规则,若结果为 NaN,则调用 toString() 方法之后应用上述规则,对象变量变成数值变量

    2. 一元加减操作符

    一元加操作符置于非数字值之前时(置于之后会被认为是一个二元操作符),该操作符会像转型函数 Number() 一样对这个值执行转换。
    一元减操作符主要用于表示负数,应用于非数字值时与一元加操作符类似。


    位操作符

    ECMAScript 中的所有数值都以 IEEE-754 64 位格式存储。位操作符不直接操作 64 位值,而是先将 64 位的值转换为 32 位的整数,然后执行操作,最后将结果转回 64 位。因此在实际操作过程中只存在 32 位整数。
    对于有符号的整数,32 位中的前 31 位用于表示整数的值,第 32 位用于表示数值(符号位),0 表示正数,1 表示负数。
    正负数都以二进制码存储,其中负数以其绝对值的二进制补码格式存储,计算补码的步骤如下:

    1. 求这个数值绝对值的二进制码
    2. 对二进制值求反码(0 换成 1,1 换成 0)
    3. 得到的反码加1

    注意处理负数时,符号位是不能访问的。
    把一个负数转换为二进制字符串,结果并不会显示补码,例如 (-6).toString(2) 的结果为"-0110",显然这种形式更符合逻辑。
    默认情况下,ECMAScript 中所有整数都是有符号数。无符号数可以表示的值更大,因为多出一位来表示数值,但它不能表示负数。

    在 ECMAScript 中,对数值应用位操作符时,后台自动将 64 位值转换为 32 位值,然后执行位操作,最后转回 64 位值。这会导致一个严重的问题:对 NaN 和 Infinity 值应用位操作符,它们会被当作 0 来处理。
    在 ECMAScript 中,对非数值应用位操作符时,会先使用 Number() 函数转换为数值,再执行位操作,得到的结果是一个数值。

    1. 按位非(NOT)

    由一个波浪线(~)表示,执行结果是该数值的反码(负数以其绝对值的二进制补码格式存储,补码 = 反码 + 1)。
    对 5(二进制:101)求反码,结果为 -6(二进制:1111 1111 1111 1111 1111 1111 1111 1010);
    对 -5(二进制:1111 1111 1111 1111 1111 1111 1111 1011)求反码,结果为 4(二进制:100)。
    可知按位非的本质就是:操作数的负值减 1。虽然通过算术式(-a-1)能得到相同结果,但是按位非的速度更快。

    2. 按位与(AND)

    由一个与字符(&)表示,它将两个数值按位对齐,只有两个对应位都是 1 时才返回 1,否则返回 0。例如求 25 & 3 :

    25:    0000 0000 0000 0000 0000 0000 0001 1001  
    3:     0000 0000 0000 0000 0000 0000 0000 0011  
    &:     0000 0000 0000 0000 0000 0000 0000 0001
    

    3. 按位或(OR)

    由一个竖线(|)表示,它将两个数值按位对齐,只有两个对应位都是 0 时才返回 0,否则返回 1。例如求 25 | 3:

    25:    0000 0000 0000 0000 0000 0000 0001 1001  
    3:     0000 0000 0000 0000 0000 0000 0000 0011  
    |:     0000 0000 0000 0000 0000 0000 0001 1011
    

    4. 按位异或(XOR)

    由一个插入符(^)表示,它将两个数值按位对齐,只有两个对应位值不同时才返回 1,否则返回 0。例如求 25 ^ 3:

    25:    0000 0000 0000 0000 0000 0000 0001 1001  
    3:     0000 0000 0000 0000 0000 0000 0000 0011  
    ^:     0000 0000 0000 0000 0000 0000 0001 1010
    

    5. 左移

    由两个小于号(<<)表示,它将数值所有位向左移动指定位数,低位补零。例如求 2 << 5:

    2:     0000 0000 0000 0000 0000 0000 0000 0010  
    64:    0000 0000 0000 0000 0000 0000 0100 0000
    

    通常,左移不会影响符号位,左移 n 位相当于乘以 2 的 n 次方。但如果左移位数过多,可能会覆盖符号位,使得符号位改变或者丢失高位的问题,例如 2 << 30 的结果是 -2147483648,2 << 31 的结果是 0。

    6. 右移

    分为有符号右移(或算术右移)和无符号右移(或逻辑右移)。

    • 有符号右移
      由两个大于号(>>)表示,它将数值所有位向右移动指定位数,符号位为1则高位补 1,否则补 0。
    • 无符号右移
      由 3 个大于号(>>>)表示,它将数值所有位向右移动指定位数,不考虑符号位,高位补 0。
      由于负数是以其绝对值的二进制补码的格式表示,所以负数的无符号右移的结果会非常大。

    布尔操作符

    1. 逻辑非

    由一个叹号(!)表示,可以应用于 ECMAScript 中的任何值,返回一个布尔值。逻辑非操作符会将操作的值转换为一个布尔值,取反并返回。转换规则如下:

    • 对象,返回 false
    • 空字符串,返回 true
    • 非空字符串,返回 false
    • 数值 0,返回 true
    • 数值 NaN,返回 true
    • 非 0 非 NaN 数值(包括 Infinity),返回 false
    • null,返回 true
    • undefined,返回 true
      同时使用两个逻辑非操作符,可以将一个值转换为与其对应的布尔值,与 Boolean() 转型函数的结果相同。

    2. 逻辑与

    由两个和号(&&)表示,可以应用于 ECMAScript 中的任何值。JavaScript 首先将 && 两边的值转成 Boolean 类型,然后再算结果,返回 true 时取后面的值,否则取前面的值。
    数值转换为 Boolean 类型 遵循以下规则:

    • 操作数为 false、null、undefined、0 和 NaN、'',则返回 false
    • 操作数为其他,则返回 true
      逻辑与是短路操作,第一个数值得 false 就会直接返回第一个值,不再计算第二个。

    3. 逻辑或

    由两个竖线符号(||)表示,可以应用于 ECMAScript 中的任何值。JavaScript 首先将||两边的值转成 Boolean 类型,然后再算结果,返回 true 时取前面的值,否则取后面的值。
    逻辑或也是短路操作,第一个数值得 true 就会直接返回第一个值。


    乘性操作符

    ECMAScript 定义了 3 个乘性操作符:乘法、除法、求模。
    如果参与乘性计算的某个操作数不是数值,操作符会自动使用 Number() 转型函数执行类型转换。

    1. 乘法

    由一个星号(*)表示,处理特殊值的情况下,乘法操作符遵循下列规则:

    • 如果有一个操作数是 NaN,则结果为 NaN
    • Infinity 与 Infinity 相乘,则结果是 Infinity
    • Infinity 与 0 相乘,则结果是 NaN
    • Infinity 与非 0 数值相乘,则结果是 Infinity 或 -Infinity
    • 如果有操作数不是数值,则调用 Number() 转换为数值,再应用上面的规则

    2. 除法

    由一个斜线号(/)表示,处理特殊值的情况下,除法操作符遵循下列规则:

    • 如果有一个操作数是 NaN,则结果为 NaN
    • Infinity 被 Infinity 除,则结果是 NaN
    • Infinity 被 0 除,则结果是 Infinity
    • Infinity 被非 0 有限数除,则结果是 Infinity 或 -Infinity
    • 非 0 有限数被 Infinity 除,则结果是 0
    • 非 0 有限数被 0 除,则结果是 Infinity 或 -Infinity
    • 0 被 Infinity 除,则结果是 0
    • 0 被 0 除,则结果是 NaN
    • 如果有操作数不是数值,则调用 Number() 转换为数值,再应用上面的规则

    3. 求模

    由一个百分号(%)表示,处理特殊值的情况下,求模操作符遵循下列规则:

    • 如果有一个操作数是 NaN,则结果为 NaN
    • Infinity 对任意数取模,则结果是 NaN
    • 任意数对 0 求模,则结果是 NaN
    • 有限数(包括 0)对 Infinity 求模,则结果是该有限数本身
    • 如果有操作数不是数值,则调用 Number() 转换为数值,再应用上面的规则

    加性操作符

    1. 加法

    由一个加号(+)表示,处理特殊值的情况下,加法操作符遵循下列规则:

    • 如果两个操作数都是字符串,则将其拼接起来
    • 如果只有一个操作数是字符串,则调用另一个操作数的相应方法(对象,数值和布尔值调用其 toString() 方法,undefined 和 null 调用 String() 方法)取得其字符串,然后拼接起来
    • 如果有一个操作数是 NaN,且另一个操作数不是字符串,则结果为 NaN
    • Infinity 加 Infinity,则结果是 Infinity
    • -Infinity 加 -Infinity,则结果是 -Infinity
    • Infinity 加 -Infinity,则结果是 NaN
    • -0 加 -0,则结果是 -0
    • 0 加 -0 或者 -0 加 0,则结果是 0
    • 如果有一个操作数是对象,则调用其 toString() 方法取得对应的字符串,然后拼接起来;如果该对象的 prototype 链中都没有实现自己的 toString() 的话,就会调用 Object.prototype.toString.call(该对象) 获取对应字符串,例如两个空白对象相加的结果是"[object Object][object Object]"(这里第一个 object 表示其数据类型,与 typeof() 功能一样,第二个 Object 表示其构造方法)
    • 如果有一个操作数是布尔值,undefined 或 null,则调用 Number() 方法取得对应的数值,然后相加

    2. 减法

    由一个减号(-)表示,处理特殊值的情况下,减法操作符遵循下列规则:

    • 如果有一个操作数是 NaN,另一个操作数不是字符串,则结果为 NaN
    • Infinity 减 Infinity,则结果是 NaN
    • -Infinity 减 -Infinity,则结果是 NaN
    • Infinity 减 -Infinity,则结果是 Infinity
    • -Infinity 减 Infinity,则结果是 -Infinity
    • 0 减 0,则结果是 0
    • 0 减 -0,则结果是 0
    • -0 减 0,则结果是 -0
    • -0 减 -0,则结果是 0
    • 如果有一个操作数是字符串、布尔值、undefined 或 null,则调用 Number() 函数将其转换为数值
    • 如果有一个操作数是对象,则调用其 valueOf() 方法以获取该对象的数值,如果没有 valueOf() 方法则调用其 toString() 方法,并将得到的字符串通过 Number 转换为数值

    关系操作符

    由小于(<)、大于(>)、小于等于(<=)和大于等于(>=)组成,处理特殊值的情况下,关系操作符遵循下列规则:

    • 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值(从第一个字符开始比较,如果相同则比较下一个,可以通过调用该字符串的 charCodeAt() 方法获取其编码值)
    • 如果有一个操作数是数值,则将另一个操作数转换为数值(转换失败时直接返回 NaN,任何值与NaN比较结果都为 false),然后进行比较
    • 如果有一个操作数是对象,则调用其 valueOf() 方法以获取对应值,再按照前面的规则进行比较,如果没有 valueOf() 方法则调用其 toString() 方法
    • 如果有一个操作数是布尔值,则先将其转换为数值,然后进行比较

    相等操作符

    ECMAScript 提供两组操作符:相等与不相等(先转换为相似类型再比较),和全等与不全等(仅比较不进行转换)

    1. 相等和不相等

    相等操作符由两个等于号(==)表示,不相等操作符由(!=)表示,比较前都会先转换操作数(强制转换),转化时遵循下列基本规则:

    • null 或 undefined 不会被转换,直接进行比较
    • 布尔值被转换为数值(true 为 1,false 为 0),然后进行比较
    • 如果有一个操作数是字符串,另一个是数值,则先将字符串转换为数值,再进行比较
    • 如果有一个操作数是对象,而另一个不是对象,则调用对象的 valueOf() 方法,用得到的值进行比较
      比较时遵循下列规则:
    • null 和 undefined 相等(它们也与自身相等,除此之外不与其他值相等)
    • 如果有一个操作数是 NaN,则判断其不相等(两个操作数都是 NaN 结果也是不相等,因为 NaN 不等于 NaN)
    • 如果两个操作数都是对象,则比较它们是否为同一个对象

    2. 全等和不全等

    全等操作符由 3 个等于号(=)表示,不全等操作符由(!)表示,全等没有转换步骤,直接进行比较
    null 和 undefined 不全等
    为了保持代码中数据类型完整性,推荐使用全等操作符


    条件操作符

    遵循与 Java 中条件操作符相同的语法形式:
    条件 ? 返回值1 : 返回值2
    条件的结果为 true 则得到返回值 1,否则得到返回值 2


    赋值操作符

    由等号表示,作用就是把右侧的值赋给左侧的值
    在等号前面加上其他算术操作符,可以组成复合赋值操作符:
    a *= b 相当于 a = a * b
    /=、%=、+=、-= 与之类似

    • 左移赋值:<<=(相当于乘以 2 的n次方,注意 JavaScript 的数字是 64 位有符号数,左移可能改变符号位)
    • 右移赋值:>>=(相当于除以 2 的 n 次方,左边补上符号位)
    • 无符号右移赋值:>>>= (左边始终补 0)
      复合运算符不会带来性能上的提升

    逗号操作符

    用于在一条语句中执行多个操作,声明多个变量。
    此外还可用于赋值,如:
    var a = (1,2,3); //此时逗号操作符只会返回最后一项

  • 相关阅读:
    SQL2008-表对表直接复制数据
    delphi debug release区别是什么?
    javascript中的for in循环和for in循环的使用陷阱
    JS操作DOM节点大全
    JS中for循环里面的闭包问题的原因及解决办法
    使用sessionStorage、localStorage存储数组与对象
    JS中substr和substring的用法和区别
    HBuilder使用夜神模拟器调试Android应用
    JSON.parse()和JSON.stringify()
    url中的特殊符号含义
  • 原文地址:https://www.cnblogs.com/zhangjun2013551829/p/9450489.html
Copyright © 2020-2023  润新知