JavaScript 操做符(一)

一元操做符

只能操做一个值的操做符叫作一元操做符。是ECMAScript中最简单的操做符。函数

递增和递减操做符

  • 执行前置递增递减操做时,变量的值是在语句被求值以前改变的。(在计算机科学领域,这种状况一般被称为副效应).
  • 执行后置递增递减操做时,变量的值是在语句被求值以后改变的。
  • 当一条语句只有递增或递减操做时,前置和后置没有区别。
let num1 = 1;
++num1;
console.log(num1); // 2

let num2 = 1;
num2++;
console.log(num1); // 2

let num3 = 1;
console.log(++num3); // 2

let num4 = 1;
console.log(num4++); // 1

let num5 = 2;
let num6 = 20;
let num7 = --num5 + num6; // 21
let num8 = num5 + num6; // 21 上面的语句改变了num5的值

let num9 = 2;
let num10 = 20;
let num11 = num9-- + num10; // 22
let num12 = num9 + num10; // 21 上面的语句改变了num5的值

除了适用于整数,还有能够用于字符串、布尔值、浮点数值、对象。最终都变为数值变量。设计

  • String:包含有效数字字符则先转为数值,再执行加减1;不包含有效数字字符则将变量值设置为NaN。
  • Boolean:将 true(false) 转为 1(0),再执行加减1。
  • Object: 先调用 valueOf() 得到一个可供操做的值,而后对该值应用前述规则。若是结果是NaN,则调用 toString() 后再应用前述规则。
let s1 = "2", s2 = "str";
let b1 = true, b2 = false;
let f = 1.1;
let o1 = {
  valueOf() {
    return 10;
  }
}
let o2 = {
  valueOf() {
    return NaN;
  }
}
console.log(++s1); // 3
console.log(++s2); // NaN
console.log(++b1); // 2
console.log(++b2); // 1
console.log(--f); // 0.10000000000000009 (因为浮点舍入错误所致)
console.log(--o1); // 9
console.log(--o2); // NaN

一元加和减操做符

在变量前使用一元操做符:

  • Number: 不变
  • String:包含有效数字字符则先转为数值;不包含有效数字字符则将变量值设置为NaN。
  • Boolean:将 true(false) 转为 1(0)。
  • Object: 先调用 valueOf() 和(或)toString() 方法,再转换获得的值。
let n = 1;
let s1 = "10", s2 = "10a", s3 = "a10", s4 = "a";
let b1 = true, b2 = false;
let f = 1.1;
let o1 = {
  valueOf(){
    return 10;
  }
}, o2 = {
  valueOf(){
    return NaN;
  }
}

console.log(+n); // 1

console.log(+s1); // 10
console.log(+s2); // NaN
console.log(+s3); // NaN
console.log(+s4); // NaN

console.log(+b1); // 1
console.log(+b2); // 0
console.log(+f); // 1.1
console.log(+o1); // 10
console.log(+o2); // NaN

在变量前使用一元操做符:

遵循一元加操做符规则,最后将获得的数值转换为负数。code

位操做符

  • 位操做符是按内存中表示数值的位来操做数值。速度快。
  • 位操做符就是先将64位的值转换成32位的整数,而后执行操做,再将结果转换为64位。ECMAScript中的数值都是以IEEE-754 64位格式存储。
  • 位操做符对 NaNInfinity 当作 0 来处理。
  • 对于非数值,会先使用 Number() 函数将该值转换为一个数值(自动完后),再执行操做,最终获得一个数值。
  • 在处理有符号的整数时,是不能访问位31的。

对于有符号的整数,32位中的前31位用于表示整数的值。第32位用于表示数值的符号:0表示整数,1表示负数。这个表示符号的位叫作符号位,它的值决定了其余位数值的格式。默认状况下,ECMAScript 中的全部整数都是有符号整数,不过也存在无符号整数。对于无符号整数,第32位再也不表示符号,那么它能表示的值天然能够更大。对象

正数以纯二进制格式存储:ip

例如数值18的二进制:00000000000000000000000000010010内存

负数以二进制补码的格式存储:字符串

二进制补码计算方式:get

  1. 求这个数值绝对值的二进制码。
  2. 求二进制反码。0替换为1,1替换为0。
  3. 获得的二进制反码加1。

获取 -18 的二进制码:it

  1. 首先求得 18 的二进制码即:
    0000 0000 0000 0000 0000 0000 0001 0010
  2. 求二进制反码:
    1111 1111 1111 1111 1111 1111 1110 1101
  3. 将二进制反码加1:
    1111 1111 1111 1111 1111 1111 1110 1110

ECMAScript会尽力向咱们隐藏全部上面的这些操做,以更合乎逻辑的形式展示出来console

const num = -18;
num.toString(2); // "-10010"

按位非(NOT)

由符号 ~ 表示,返回数值的反码。本质就是操做数的负值减1。

const n1 = 25; //  二进制 00000000000000000000000000011001
const n2 = ~n1; // 二进制 11111111111111111111111111100110
console.log(n2); // -26   这里也解释了为何计算二进制补码的第3步要加1。

按位与(AND)

由符号 & 表示。两个数值对应位都是1才返回1,不然返回0

const result = 25 & 3;
console.log(result); // 1

// 二进制:
//  25 = 00000000000000000000000000011001
//   3 = 00000000000000000000000000000011
// AND = 00000000000000000000000000000001

按位或(OR)

由符号 | 表示。两个数值对应位有一个1就返回1,不然返回0

const result = 25 | 3;
console.log(result); // 27

// 二进制:
//  25 = 00000000000000000000000000011001
//   3 = 00000000000000000000000000000011
//  OR = 00000000000000000000000000011011

按位异或(XOR)

由符号 ^ 表示。两个数值对应位只有一个1才返回1,不然返回0

const result = 25 ^ 3;
console.log(result); // 26

// 二进制:
//  25 = 00000000000000000000000000011001
//   3 = 00000000000000000000000000000011
//  OR = 00000000000000000000000000011010

左移

由符号 << 表示。将数值的全部位向左移动指定位数。

左移不会影响操做数的符号位。例如:将 -2 向左移动 5 位,结果将是 -64 ,而非 64。
const result = 2 << 5;
console.log(result); // 64

// 二进制:
//      2 = 00000000000000000000000000000010
// result = 00000000000000000000000001000000

有符号的右移

由符号 >> 表示。将数值的向右移动指定位数,保留符号位,而且用符号位的值来填充空位。

有符号的右移与左移刚好相反。例如:将 64 向右移动 5 位,结果将是 2。
const result = 64 >> 5;
console.log(result); // 2

// 二进制:
//     64 = 00000000000000000000000001000000
// result = 00000000000000000000000000000010

无符号的右移

由符号 >>> 表示。将数值的全部位向右移动指定位数, 保留符号位,而且使用 0 来填充空位。

对于正数来讲,无符号右移与有符号右移没区别。对于负数来讲:首先空位是由 0 来填充,而不是符号位的值;其次,会把负数的二进制码(是正数二进制码的反码加1)当成正数的二进制码,也就会致使结果很是之大。
const result1 = 64 >>> 5;
console.log(result1); // 2

// 二进制:
//     64  = 00000000000000000000000001000000
// result1 = 00000000000000000000000000000010

const result2 = -64 >>> 5;
console.log(result2); // 134217726

// 二进制:
//     -64 = 11111111111111111111111111000000
// result2 = 00000111111111111111111111111110

参考

《JavaScript高级程序设计》(第三版)

相关文章
相关标签/搜索