javascript按位非运算符的使用方法


Posted in Javascript onNovember 14, 2013

~:按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。

var num1 = 3;    // 我的幸运数字是3
var num2 = ~(num1);
console.log(num2)  //  "-4"
var num3 = -3;  
var num4 = ~(num3);
console.log(num4)  //  "2"
console.log(~(0))  //  "-1"

没错,现在我们知道了~运算符的原理了。开心吗?。。。不开心,虽然这一章,我看过好多次。。。因为我从来就没用过,实在是惭愧啊。大家觉得这个运算符可以用在什么地方呢?恩。。。沉思一下,放一段同事的代码:
if (~item[search_key].toLowerCase().indexOf(query)) {
                        _results.push(item);
 }

代码:
if( str.indexOf(query) != -1 )  or  if( str.indexOf(query) >= 0)

原理分析:
通过str.indexOf(query)最后得出的值,无外乎不过两种:
1. str中包含query字符串,则值是0或正整数,此时:!!(~str.indexOf(query)) === true(或者这样转换 Boolean(~str.indexOf(query)) === true)
2. srt中不包含query字符串,则值为-1,此时:!!(~str.indexOf(query)) === false
因此通过加上一个~就能很好的对indexOf的查询结果进行判断了。清爽无比,从此再也没有头屑的烦恼了。。哈哈!
最后我们来分析一下效率吧,印象中位运算的效率应该比较运算符高。来段代码:
var str = "hutaoer go go go!!!!! My lucky number is 33!!";
    var query = 33;
    var timeStart1 = new Date() - 0;
    for(var i = 0; i < 100000000; i++) {
        ~str.indexOf(query)
    }
    var timeEnd1 = new Date() - 0;
    console.log('~ cost time:' + (timeEnd1 - timeStart1)); 
    // ~ cost time:9954  循环次数:10000000 
    // ~ cost time:104  循环次数: 100000
    var timeStart2 = new Date() - 0;
    for(var j = 0; j < 100000000; j++) {
        str.indexOf(query) >= 0
    }
    var timeEnd2 = new Date() - 0;
    console.log('>= cost time:' + (timeEnd2 - timeStart2)); 
   // >= cost time:10120  循环次数:10000000

程序更新:原来的测试代码在分割线上面不变。代码如下:
    var str = "hutaoer go go go!!!!! My lucky number is 33!!";
    var query = 33;
    var timeStart1 = new Date() - 0;
    for(var i = 0; i < 1000000; i++) {
        ~str.indexOf(query)
    }
    var timeEnd1 = new Date() - 0;
    console.log('~ cost time:' + (timeEnd1 - timeStart1));
    //  循环1000000次  127ms
    var timeStart2 = new Date() - 0;
    for(var j = 0; j < 1000000; j++) {
        str.indexOf(query) >= 0
    }
    var timeEnd2 = new Date() - 0;
    console.log('>= cost time:' + (timeEnd2 - timeStart2));
    // 循环1000000次 101ms
    var timeStart3 = new Date() - 0;
    for(var k = 0; k < 1000000; k++) {
        Boolean(~str.indexOf(query))
    }
    var timeEnd3 = new Date() - 0;
    console.log('add Boolean cost time:' + (timeEnd3 - timeStart3));
    // 循环1000000次 129ms
    var timeStart4 = new Date() - 0;
    for(var k = 0; k < 1000000; k++) {
        !!(~str.indexOf(query))
    }
    var timeEnd4 = new Date() - 0;
    console.log('add !! cost time:' + (timeEnd4 - timeStart4));
    // 循环10000000次 103ms
   

其实,对于一次运算本身来说,相差无几,只是在循环次数过大,比如超过了10000000次,效率才会有一些差距。
【更新 2013.10.27 17:28】通过修改后的测试,我们可以发现,“按位非”这中写法也许并非是效率最高的,表现最好的居然是我以前常用的写法,采用比较运算符。这确实让我很吃惊。有时候,人往往容易被常识,表象所迷惑,但亲自去尝试后,或许会有不一样的发现或得出其他的结果。今天,我算吸取教训了。
在评论中,同学们都比较反对这种非常见的写法,毕竟这些技巧可能会给阅读代码的同学造成困扰。如果不知道原理的话,甚至让人费解。或许,直接用一些简单的逻辑和常见的运算符,会是更好的选择?你们觉得呢?
因此平时写代码的时候,用哪种写法都可以。但是希望我们能将这些技巧记住,关键时刻或许就能派上用场。
Javascript 相关文章推荐
JQuery jsonp 使用示例代码
Aug 12 Javascript
初试jQuery EasyUI 使用介绍
Apr 01 Javascript
javascript中使用css需要注意的地方小结
Sep 01 Javascript
基于jQuery的获得各种控件Value的方法
Nov 19 Javascript
让ie6也支持websocket采用flash封装实现
Feb 18 Javascript
JavaScript 动态加载脚本和样式的方法
Apr 13 Javascript
CSS或者JS实现鼠标悬停显示另一元素
Jan 22 Javascript
node模块机制与异步处理详解
Mar 13 Javascript
Ubuntu系统下Angularjs开发环境安装
Sep 01 Javascript
angular.js 路由及页面传参示例
Feb 24 Javascript
vue源码学习之Object.defineProperty对象属性监听
May 30 Javascript
Nuxt.js的路由跳转操作(页面跳转nuxt-link)
Nov 06 Javascript
javascript Array.prototype.slice的使用示例
Nov 14 #Javascript
js取消单选按钮选中示例代码
Nov 14 #Javascript
js实现目录定位正文示例
Nov 14 #Javascript
通过action传过来的值在option获取进行验证的方法
Nov 14 #Javascript
javascript间隔刷新的简单实例
Nov 14 #Javascript
Enter转换为Tab的小例子(兼容IE,Firefox)
Nov 14 #Javascript
js中prototype用法详细介绍
Nov 14 #Javascript
You might like
php xml留言板 xml存储数据的简单例子
2009/08/24 PHP
Discuz!下Memcache缓存实现方法
2010/05/28 PHP
php下连接ftp实现文件的上传、下载、删除文件实例代码
2010/06/03 PHP
使用php显示搜索引擎来的关键词
2014/02/13 PHP
PHP错误Parse error: syntax error, unexpected end of file in test.php on line 12解决方法
2014/06/23 PHP
PHP获取服务器端信息的方法
2014/11/28 PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
2019/07/24 PHP
laravel框架中间件简单使用方法示例
2020/01/25 PHP
用js查找法实现当前栏目的高亮显示的代码
2007/11/24 Javascript
Jquery 快速构建可拖曳的购物车DragDrop
2009/11/30 Javascript
基于jquery的图片懒加载js
2010/06/30 Javascript
JS声明变量背后的编译原理剖析
2012/12/28 Javascript
jquery中object对象循环遍历的方法
2015/12/18 Javascript
jquery mobile开发常见问题分析
2016/01/21 Javascript
javascript中去除数组重复元素的实现方法【实例】
2016/04/12 Javascript
jquery siblings获取同辈元素用法实例分析
2016/07/25 Javascript
Webpack 4.x搭建react开发环境的方法步骤
2018/08/15 Javascript
利用chrome浏览器进行js调试并找出元素绑定的点击事件详解
2021/01/30 Javascript
vue中的router-view组件的使用教程
2018/10/23 Javascript
解决Ant Design Modal内嵌Form表单initialValue值不动态更新问题
2020/10/29 Javascript
js实现限定区域范围拖拉拽效果
2020/11/20 Javascript
Python爬虫框架Scrapy安装使用步骤
2014/04/01 Python
python脚本监控docker容器
2016/04/27 Python
python3 对list中每个元素进行处理的方法
2018/06/29 Python
python hough变换检测直线的实现方法
2019/07/12 Python
Django实现发送邮件找回密码功能
2019/08/12 Python
Pytorch Tensor的统计属性实例讲解
2019/12/30 Python
Python基于requests实现模拟上传文件
2020/04/21 Python
详解HTML5中的拖放事件(Drag 和 drop)
2016/11/14 HTML / CSS
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
C语言基础笔试题
2013/04/27 面试题
什么是数据抽象
2016/11/26 面试题
先进德育工作者事迹材料
2014/01/24 职场文书
宿舍保安职务说明书
2014/02/25 职场文书
2015年大学迎新晚会总结
2015/07/16 职场文书
Vue监视数据的原理详解
2022/02/24 Vue.js