JS 部分运算符操作

[TOC]

1. 关于对象的运算符操作

如果运算子是对象可以定义对象的valueOf 属性为函数,实际运算中通过调用该函数获取对象的实际值,在实际调用是obj.valueOf().toString() 返回一个对象的值。

> obj.valueOf = () => {return 12;}
[Function]
> obj
{ valueOf: [Function] }
> obj.valueOf()
12
> obj + 1
13
> obj > 1
true
> obj === '12'
false
> obj === 12
false
> obj == 12
true
> obj + 'test'
'12test'
> '' + obj
'12'
> '0' + obj
'012'

2. 严格相等比较

俗语严格相等比较时,如果两个值的类型不同,直接返回false,不会进行类型转化;对于同一类型的原始类型的值比较,相等则返回true;对于复合类型的数据进行比较,不是比较是否相等而是比较是否为同一地址,注意对于对象的比较,严格比较运算符比较的是地址,大于,小于比较的是对象的数值 对于三个特殊值:undefined null 与自身严格相等 NaN 与任何值严格比较均不等

> 1 === 0x1
true
> NaN === NaN
false
> [] === []
false
> {} === {}
false

3. 二进制运算符

JS中一共有7个二进制位运算符,直接处理每一个bit。需要注意的是位运算符只对整数起作用,虽然JS中所有数字都是以64位浮点数进行存储的,但是进行位运算时,是用32位带符号位的整数进行运算的,返回值也是一个32位的带符号整数。使用位运算符会有较好的性能。

可以使用| 运算符将任意数转换为32位整数,使用二进制运算符处理小数时,会将小数部分舍去,只处理整数部分

function toInt(a) {
    return a | 0;
}
toInt32(1.001) // 1
toInt32(1.999) // 1
toInt32(1) // 1
toInt32(-1) // -1
toInt32(Math.pow(2, 32) + 1) // 1
toInt32(Math.pow(2, 32) - 1) // -1

0 & 12  // 0

否运算符~:

否运算符会将所有32位整数的每一位都取反,注意数字是以补码表示,所以对于3取反后00000000000000000000011 变为 111111111111111111111100 ,补码表示的-4,取反值与原值相加为-1

对于非数字类型进行取反,会默认调用Number() 函数,先转化为数字,对于NaN null undefined 取反均为-1

> ~~109
109
> ~47.12
-48
> ~'011'
-12
> ~'0110'
-111


> ~'12 va'
-1
> Number('12 vds')
NaN
> ~[]
-1
> ~NaN
-1
> ~null
-1

带符号位的右移

js支持基本的左移运算以及右移运算,也可以进行带符号位的右移,即进行右移操作时符号位也参与移动,头部补0,所以进行该运算时得到的额结果一定为正

位运算符可以用作设置对象属性的开关

假定某个对象有四个开关,每个开关都是一个变量。那么,可以设置一个四位的二进制数,它的每个位对应一个开关。

var FLAG_A = 1; // 0001
var FLAG_B = 2; // 0010
var FLAG_C = 4; // 0100
var FLAG_D = 8; // 1000

上面代码设置 A、B、C、D 四个开关,每个开关分别占有一个二进制位。

然后,就可以用二进制与运算检验,当前设置是否打开了指定开关。

var flags = 5; // 二进制的0101

if (flags & FLAG_C) {
  // ...
}
// 0101 & 0100 => 0100 => true

上面代码检验是否打开了开关C。如果打开,会返回true,否则返回false

现在假设需要打开ABD三个开关,我们可以构造一个掩码变量。

var mask = FLAG_A | FLAG_B | FLAG_D;
// 0001 | 0010 | 1000 => 1011

上面代码对ABD三个变量进行二进制或运算,得到掩码值为二进制的1011

有了掩码,二进制或运算可以确保打开指定的开关。

flags = flags | mask;

二进制与运算可以将当前设置中凡是与开关设置不一样的项,全部关闭。

flags = flags & mask;

异或运算可以切换(toggle)当前设置,即第一次执行可以得到当前设置的相反值,再执行一次又得到原来的值。

flags = flags ^ mask;

二进制否运算可以翻转当前设置,即原设置为0,运算后变为1;原设置为1,运算后变为0

flags = ~flags;

Last updated