我读过"什么是按位运算符?" ,所以我知道运算符是什么 ,但我还不清楚如何使用它们.任何人都可以提供任何实际的例子,说明位运算符在JavaScript中有用吗?
谢谢.
只是深入研究jQuery源代码,我发现了几个使用按位运算符的地方,例如:(只有&运算符)
// Line 2756: event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); // Line 2101 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
Mark.. 66
例:
解析十六进制值以获取RGB颜色值.
var hex = 'ffaadd'; var rgb = parseInt(hex, 16); // rgb is 16755421 var red = (rgb >> 16) & 0xFF; // returns 255 var green = (rgb >> 8) & 0xFF; // 170 var blue = rgb & 0xFF; // 221
代码取自http://www.phpied.com/bitwise-operations-in-javascript/ (9认同)
@SebastianBarth怎么回事?这段代码中没有任何字符编码与远程相关的部分. (4认同)
Dan.. 44
我大量使用在生产脚本数字convertions位运算符,因为有时他们比他们快得多Math
或parseInt
等价物.
我必须付出的代价是代码可读性.所以我通常用于Math
开发和按位生产.
你可以在jsperf.com上找到一些性能技巧.
正如你所看到的,浏览器不优化Math.ceil
和parseInt
多年,所以我预测按位会更快和更短的方式来做事的furure也.
关于SO的一些进一步阅读......
奖励:小抄为 | 0
:一个简单,快捷的方式,以任何转换为整数:
( 3|0 ) === 3; // it does not change integers ( 3.3|0 ) === 3; // it casts off the fractional part in fractionalal numbers ( 3.8|0 ) === 3; // it does not round, but exactly casts off the fractional part ( -3.3|0 ) === -3; // including negative fractional numbers ( -3.8|0 ) === -3; // which have Math.floor(-3.3) == Math.floor(-3.8) == -4 ( "3"|0 ) === 3; // strings with numbers are typecast to integers ( "3.8"|0 ) === 3; // during this the fractional part is cast off too ( "-3.8"|0 ) === -3; // including negative fractional numbers ( NaN|0 ) === 0; // NaN is typecast to 0 ( Infinity|0 ) === 0; // the typecast to 0 occurs with the Infinity ( -Infinity|0 ) === 0; // and with -Infinity ( null|0 ) === 0; // and with null, ( (void 0)|0 ) === 0; // and with undefined ( []|0 ) === 0; // and with an empty array ( [3]|0 ) === 3; // but an array with one number is typecast to number ( [-3.8]|0 ) === -3; // including the cast off of the fractional part ( [" -3.8 "]|0 ) === -3; // including the typecast of strings to numbers ( [-3.8, 22]|0 ) === 0 // but an Array with several numbers is typecast to 0 ( {}|0 ) === 0; // an empty object is typecast to 0 ( {'2':'3'}|0 ) === 0; // or a not empty object ( (function(){})|0 ) === 0; // an empty function is typecast to 0 too ( (function(){ return 3;})|0 ) === 0;
对我来说还有一些魔力:
3 | '0px' === 3;
所有这20行左右的例子都可以用一句话来表达:**按位运算符使用32位,二进制补码大端(简称32位)表示数字,所以它们的任何操作数都是如此根据以下规则将数据转换为此格式:数字从IEEE-754 64位格式转换为32位,其他任何内容首先转换为ECMAScript规范中指定的数字(即,对象(用于对象)是对象,数组,函数)通过调用其valueOf方法)然后将此数字转换为32位格式** (4认同)
这不是一个好的答案.起初它看起来像一个参考并且有很多信息(我昨天甚至赞成它),但经过更深入的研究后,事实证明这不是真的. (2认同)
Mathias Byne.. 24
在JavaScript中,您可以使用双位否定(~~n
)替换Math.floor(n)
(如果n
是正数)或parseInt(n, 10)
(即使n
是负数).n|n
并n&n
始终产生相同的结果~~n
.
var n = Math.PI; n; // 3.141592653589793 Math.floor(n); // 3 parseInt(n, 10); // 3 ~~n; // 3 n|n; // 3 n&n; // 3 // ~~n works as a replacement for parseInt() with negative numbers… ~~(-n); // -3 (-n)|(-n); // -3 (-n)&(-n); // -3 parseInt(-n, 10); // -3 // …although it doesn’t replace Math.floor() for negative numbers Math.floor(-n); // -4
单个按位取反(~
)计算-(parseInt(n, 10) + 1)
,因此将返回两个按位否定-(-(parseInt(n, 10) + 1) + 1)
.
应该指出的是,在这三种替代方案中,n|n
似乎是最快的.
更新:更准确的基准:http://jsperf.com/rounding-numbers-down
(发布在最奇怪的语言功能)
例:
解析十六进制值以获取RGB颜色值.
var hex = 'ffaadd'; var rgb = parseInt(hex, 16); // rgb is 16755421 var red = (rgb >> 16) & 0xFF; // returns 255 var green = (rgb >> 8) & 0xFF; // 170 var blue = rgb & 0xFF; // 221
我大量使用在生产脚本数字convertions位运算符,因为有时他们比他们快得多Math
或parseInt
等价物.
我必须付出的代价是代码可读性.所以我通常用于Math
开发和按位生产.
你可以在jsperf.com上找到一些性能技巧.
正如你所看到的,浏览器不优化Math.ceil
和parseInt
多年,所以我预测按位会更快和更短的方式来做事的furure也.
关于SO的一些进一步阅读......
奖励:小抄为 | 0
:一个简单,快捷的方式,以任何转换为整数:
( 3|0 ) === 3; // it does not change integers ( 3.3|0 ) === 3; // it casts off the fractional part in fractionalal numbers ( 3.8|0 ) === 3; // it does not round, but exactly casts off the fractional part ( -3.3|0 ) === -3; // including negative fractional numbers ( -3.8|0 ) === -3; // which have Math.floor(-3.3) == Math.floor(-3.8) == -4 ( "3"|0 ) === 3; // strings with numbers are typecast to integers ( "3.8"|0 ) === 3; // during this the fractional part is cast off too ( "-3.8"|0 ) === -3; // including negative fractional numbers ( NaN|0 ) === 0; // NaN is typecast to 0 ( Infinity|0 ) === 0; // the typecast to 0 occurs with the Infinity ( -Infinity|0 ) === 0; // and with -Infinity ( null|0 ) === 0; // and with null, ( (void 0)|0 ) === 0; // and with undefined ( []|0 ) === 0; // and with an empty array ( [3]|0 ) === 3; // but an array with one number is typecast to number ( [-3.8]|0 ) === -3; // including the cast off of the fractional part ( [" -3.8 "]|0 ) === -3; // including the typecast of strings to numbers ( [-3.8, 22]|0 ) === 0 // but an Array with several numbers is typecast to 0 ( {}|0 ) === 0; // an empty object is typecast to 0 ( {'2':'3'}|0 ) === 0; // or a not empty object ( (function(){})|0 ) === 0; // an empty function is typecast to 0 too ( (function(){ return 3;})|0 ) === 0;
对我来说还有一些魔力:
3 | '0px' === 3;
在JavaScript中,您可以使用双位否定(~~n
)替换Math.floor(n)
(如果n
是正数)或parseInt(n, 10)
(即使n
是负数).n|n
并n&n
始终产生相同的结果~~n
.
var n = Math.PI; n; // 3.141592653589793 Math.floor(n); // 3 parseInt(n, 10); // 3 ~~n; // 3 n|n; // 3 n&n; // 3 // ~~n works as a replacement for parseInt() with negative numbers… ~~(-n); // -3 (-n)|(-n); // -3 (-n)&(-n); // -3 parseInt(-n, 10); // -3 // …although it doesn’t replace Math.floor() for negative numbers Math.floor(-n); // -4
单个按位取反(~
)计算-(parseInt(n, 10) + 1)
,因此将返回两个按位否定-(-(parseInt(n, 10) + 1) + 1)
.
应该指出的是,在这三种替代方案中,n|n
似乎是最快的.
更新:更准确的基准:http://jsperf.com/rounding-numbers-down
(发布在最奇怪的语言功能)
一个真实的 例子:
^
按位异或作为I/O
toggler使用像value ^= 1
会改变每个调用value
到0, 1, 0, 1 ...
function toggle(evt) {
evt.target.IO ^= 1; // Bitwise XOR as 1/0 toggler
evt.target.textContent = evt.target.IO ? "ON" : "OFF"; // Unleash your ideas
}
document.querySelectorAll("button").forEach( el =>
el.addEventListener("click", toggle)
);
鉴于Javascript正在取得的进步(特别是对于允许使用js进行服务器端编程的nodejs),JS中的代码越来越复杂.以下是我使用按位运算符的几个实例:
IP地址操作:
//computes the broadcast address based on the mask and a host address broadcast = (ip & mask) | (mask ^ 0xFFFFFFFF) //converts a number to an ip adress sprintf(ip, "%i.%i.%i.%i", ((ip_int >> 24) & 0x000000FF), ((ip_int >> 16) & 0x000000FF), ((ip_int >> 8) & 0x000000FF), ( ip_int & 0x000000FF));
注意:这是C代码,但JS几乎完全相同
CRC算法使用它们很多
退房的维基百科条目上这
屏幕分辨率操作
要判断一个数字是否奇怪:
function isOdd(number) { return !!(number & 1); } isOdd(1); // true, 1 is odd isOdd(2); // false, 2 is not odd isOdd(357); // true, 357 is odd
比模数更快 - 在性能真正重要的地方使用!
关于如何使用按位而不是双按位的其他几个示例:
地板操作
~~2.5 // 2 ~~2.1 // 2 ~~(-2.5) // -2
检查indexOf是否返回-1
var foo = 'abc'; !~foo.indexOf('bar'); // true
您可以使用它们来翻转布尔值:
var foo = 1; var bar = 0; alert(foo ^= 1); alert(bar ^= 1);
这有点傻,但在大多数情况下,按位运算符在Javascript中没有很多应用程序.
var arr = ['abc', 'xyz']
生气地写
if (arr.indexOf('abc') > -1) { // 'abc' is in arr } if (arr.indexOf('def') === -1) { // 'def' is not in arr }
检查数组中是否有东西?
您可以~
像这样使用按位运算符:
if (~arr.indexOf('abc')) { // 'abc' is in arr } if (! ~arr.indexOf('def')) { // 'def' is not in arr }