我在哪里可以在JavaScript中使用一个按位运算符?

我读过这个 ( https://stackoverflow.com/quest … ),所以我知道什么是按位运算符,但我仍然不清楚如何使用它们…任何人都可以提供任何现实世界一个位运算符在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; 

例:

分析hex值以获取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 

我在生产脚本中大量使用按位运算符进行数值转换,因为有时它们比MathparseInt等价物快得多。

我必须支付的代价是代码可读性 。 所以我通常在开发中使用Math和在生产中逐位。

你可以在jsperf.com上find一些性能方面的技巧 。

正如你所看到的,浏览器不会优化Math.ceilparseInt多年,所以我预测按位将会更快,更短的方式来做事情。

一些关于SO的进一步阅读…


奖金: 作弊表 | 0 | 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是负数)的replace。 n|nn&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)

应该指出的是,在这三种select中, n|n似乎是最快的

更新:更准确的基准在这里: http : //jsperf.com/rounding-numbers-down

(在最奇怪的语言function张贴)

一个真实的例子? :

^ (按位异或)作为I/O触发器

jsBin例子

使用类似value ^= 1将在每次调用时将value更改为0, 1, 0, 1 ...
如果我们将该value作为语句传递给条件运算符 (?:)就像

 statement ? (if true) : (if false) 

并检查0=false, 1=true的布尔表示,我们可以切换文本,类,样式….任何需要像ie:一个button文本:

 value ? "Close dropdown" : "Open dropdown"; 

对于单个元素 ,切换function可能如下所示:

 // USING GLOBAL VARIABLE var tog = 0; var btn = document.getElementById('myButton'); function toggler(){ tog ^= 1; this.innerHTML = tog ? "hide" : "show"; } btn.addEventListener('click', toggler, false); 

对于多个元素,我们可以将togvariables状态直接存储到thisElementHTML 对象中,如:

 // WITHOUT GLOBAL VARIABLE var btns = document.getElementsByClassName('myButton'); function toggler(){ var tog = this.tog ^= 1; // get/set tog value out of this.tog object this.innerHTML = tog ? "hide" : "show"; } for(var i=0; i<btns .length; i++){ btns[i].addEventListener('click', toggler, false); } 

或者,如果你不喜欢this想法,去标准的dataset属性属性;)

鉴于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几乎是相同的

  • CRCalgorithm使用它们很多

看看这个维基百科条目

  • 屏幕分辨率操作

要知道一个数字是否奇怪:

 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中没有很多应用程序。

位掩码

广泛使用,例如,JS事件。

 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 } 

我曾经使用它一次的权限小部件 。 unix中的文件权限是一个位掩码,所以要parsing它,你需要使用位操作。

我使用它们将三个数字拼合成1,作为在Uint16Array中存储multidimensional array的一种方式 。 这里是我正在开发的体素游戏的片段:

 function Chunk() { this._blocks = new Uint16Array(32768); this._networkUpdates = []; } Chunk.prototype.getBlock = function(x, y, z) { return this._blocks[y + (x << 5) + (z << 10)]; }; Chunk.prototype.setBlock = function(x, y, z, value) { this._blocks[y + (x << 5) + (z << 10)] = value; this._networkUpdates.push(value + (y << 15) + (x << 20) + (z << 25)); }; Chunk.prototype.getUpdates = function() { return this._networkUpdates; }; Chunk.prototype.processUpdate = function(update) { // this._blocks[Math.floor(update / 65536)] = update % 65536; this._blocks[update >> 16] = update & 65535; }; var chunk = new Chunk(); chunk.setBlock(10, 5, 4); alert(chunk.getBlock(10, 5, 4)); alert(chunk.getUpdates()[0]); 

当你使用hex值和位时,它们似乎非常有用。 由于4位可以表示0到F.

1111 = F 1111 1111 = FF。

使用Node.js的例子

假定你有一个文件(称为multiply.js)与这些内容,你可以运行

 `node multiply <number> <number>` 

并获得与在相同的两个数字上使用乘法运算符一致的输出。 在Mulitply函数中进行的Mulitply是一个例子,表示如何取代表示一个数字的位掩码,并使用它来翻转另一个数字中的位来进行快速操作。

 var a, b, input = process.argv.slice(2); var printUsage = function() { console.log('USAGE:'); console.log(' node multiply <number> <number>'); } if(input[0] === '--help') {+ printUsage(); process.exit(0); } if(input.length !== 2) { printUsage(); process.exit(9); } if(isNaN(+input[0]) || isNaN(+input[1])) { printUsage(); process.exit(9); } // Okay, safe to proceed a = parseInt(input[0]), b = parseInt(input[1]); var Multiply = function(a,b) { var x = a, y = b, z = 0; while( x > 0 ) { if(x % 2 === 1) { z = z + y; } y = y << 1; x = x >> 1; } return z; } var result = Multiply(a,b); console.log(result); 

我只是发现这个问题,试图确认是否按位AND运算符也是在Javascript中。

既然你问了一个例子:

 if ($('input[id="user[privileges]"]').length > 0) { $('#privileges button').each(function () { if (parseInt($('input[id="user[privileges]"]').val()) & parseInt($(this).attr('value'))) { $(this).button('toggle'); } }); } 

它使用jQuery给出一个隐藏字段的位掩码值来填充button的状态:

  • none = 0
  • user = 1
  • administrator = 2
  • user + administrator = 3