1、 JS运算符 — 位运算符 一. 按位与运算符(&) 1. 该运算符对它的运算数逐位执行布尔AND操作,只有两个运算数中相应的位都为1时,结果中的这一位才为1,它要求其运算数为整型,如果运算数不是整型,则会尝试将其转换为32位整型,如果无法转换,就返回NaN。 // 运算数均为整型 alert(9 & 9); // 9 alert(9 & 10); // 8 alert(1 & 3); // 1 // 运算数可以被转换为整型 alert([9] & '9'); // 9 alert([9] & ['10']); // 8 alert(1.25 & 3.25); //
2、1 // 一个或两个运算数均无法被转换整型 alert(1 & ['a']); // 0 alert({} & /\d/); // 0 alert(NaN & NaN); // 0 alert(Infinity & Infinity); // 0 alert(NaN & Infinity); // 0 alert(null & null); // 0 alert(undefined & undefined); // 0 alert(null & undefined); // 0 二. 按位或运算符(|) 1. 该运算符对它的运算数逐位执行布尔OR操作,如果其中一个运算
3、数中相应位为1或者两个运算数中的相应位都为1,结果中的这一位就为1,它要求其运算数为整型,如果运算数不是整型,则会尝试将其转换为32位整型,如果无法转换,就返回NaN。 // 运算数均为整型 alert(9 | 9); // 9 alert(9 | 10); // 11 alert(1 | 3); // 3 // 运算数可以被转换为整型 alert([9] | '9'); // 9 alert([9] | ['10']); // 11 alert(1.25 | 3.25); // 3 // 一个运算数无法被转换整型 alert(1 | ['a']); // 1 a
4、lert(10 | null); // 10 alert(100 | NaN); // 100 // 两个运算数均无法被转换成整型 alert({} | /\d/); // 0 alert(NaN | NaN); // 0 alert(Infinity | Infinity); // 0 alert(NaN | Infinity); // 0 alert(null | null); // 0 alert(undefined | undefined); // 0 alert(null | undefined); // 0 三. 按位非运算符(~) 1. 该运算符的作用,
5、相当于改变运算数的符号并减1。它要求其运算数为整型,如果运算数不是整型,则会尝试将其转换为32位整型,如果无法转换,就返回NaN。 alert(~5); // 相当于-5 - 1 = -6 alert(~{}); // -1 alert(~[]); // -1 alert(~[10]); // -11 alert(~'10'); // -11 alert(~'aa'); // -1 alert(~/\d/); // -1 alert(~undefined); // -1 alert(~Infinity); // -1 alert(~NaN); // -1 alert(~n
6、ull); // -1 alert(~function() {}); // -1 2. ~的运算原理 // 网上有个老外对~~的运算原理做了分析,他的分析如下(以~~foo为例,foo是经过整型转换后的结果): typeof foo === 'number' && !isNaN(foo) && foo !== Infinity ? foo > 0 ? Math.floor(foo) : Math.ceil(foo) : 0; // 基于老外的分析,~的运算原理可以想象为这样: typeof foo === 'number' && !isNaN(foo) && foo !== I
7、nfinity ? foo > 0 ? -(Math.floor(foo) + 1) : -(Math.ceil(foo) + 1) : -1; 3. 一个较特殊的例子 alert(~function(){alert(20);}()); // 先输出20,然后输出-1,why??? // 分析: (1) "()"的优先级要高于"~",所以function(){alert(20);}会先与()结合,再与~结合; (2) ~会执行其后的语句,但执行结果不会成为运算数,即~function(){alert(20);}()不会成为~20; (3) ~还会对其后的语句进行求值运算,我们通
8、过模拟来验证一下: var func = function() {alert(1);}; func.valueOf = function() {return 10;} alert(~function() {alert(1);}); // -1 alert(~func); // -11 四. 左移运算符(<<) 1. 该运算符有两个运算数:a<
9、 当运算数a无法被转换为整数时,运算结果为0。 alert({} << 2); // 0 alert(NaN << 2); // 0 alert(Infinity << 2); // 0 alert(function() {} << 2); // 0 alert(undefined << 2); // 0 alert(null << 2); // 0 3. 当运算数b无法被转转换为整数时,运算结果为运算数a,相当于a<<0。 alert(2 << {}); // 2 alert(20 << NaN); // 20 alert(10 << Infinity); // 10
10、 4. 当运算数a和b均无法被转换为整数时,运算结果为0。 alert("a" << Infinity); // 0 alert(NaN << NaN); // 0 五. 右移运算符(>>) 1. 该运算符有两个运算数:a<> 1); // Math.floor(7/2) = 3 alert(-7 >> 1); // Math.floor(-7/2) = -4 // 运算数无法被转换为整数 alert(NaN >> 1); // 0 alert(NaN >> NaN); // 0 alert(20 >> NaN); 20 六. 用0补足的右移运算符(>>>) 1. 该运算符有两个运算数:a>>>b,当运算数无法被转换成整数时,运算结果的情况与左移运算符相同。 alert("a" >>> 2); // 0 alert("a" >>> NaN); // 0 alert(20 >>> NaN); // 20






