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 相关文章推荐
让getElementsByName适应IE和firefox的方法
Sep 24 Javascript
JavaScript 读取元素的CSS信息的代码
Feb 07 Javascript
jQuery 学习第六课 实现一个Ajax的TreeView
May 17 Javascript
JS弹出对话框返回值代码(asp.net后台)
Dec 28 Javascript
javascript函数重载解决方案分享
Feb 19 Javascript
JavaScript中的事件委托及好处
Jul 12 Javascript
关于input全选反选恶心的异常情况
Jul 24 Javascript
微信小程序 页面跳转传参详解
Oct 28 Javascript
vue使用自定义指令实现拖拽
Jan 29 Javascript
layui自定义验证,用ajax查询后台是否有重复数据,form.verify的例子
Sep 06 Javascript
javascript单张多张图无缝滚动实例代码
May 10 Javascript
js 函数性能比较方法
Aug 24 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
第二节--PHP5 的对象模型
2006/11/16 PHP
php全局变量和类配合使用深刻理解
2013/06/05 PHP
多个PHP中文字符串截取函数
2013/11/12 PHP
CodeIgniter辅助之第三方类库third_party用法分析
2016/01/20 PHP
PHP大文件切割上传功能实例分析
2019/07/01 PHP
用javascript动态调整iframe高度的方法
2007/03/06 Javascript
JS的数组的扩展实例代码
2008/07/09 Javascript
jquery.Jwin.js 基于jquery的弹出层插件代码
2012/05/23 Javascript
网页广告中JS代码的信息监听示例
2014/04/02 Javascript
JQuery实现动态添加删除评论的方法
2015/05/18 Javascript
详解JavaScript时间处理之几个月前或几个月后的指定日期
2016/12/21 Javascript
CentOS 安装NodeJS V8.0.0的方法
2017/06/15 NodeJs
Javascript实现跨域后台设置拦截的方法详解
2017/08/04 Javascript
vue-router实现tab标签页(单页面)详解
2017/10/17 Javascript
关于express与koa的使用对比详解
2018/01/25 Javascript
vue实现前台列表数据过滤搜索、分页效果
2019/05/28 Javascript
vue.js 打包时出现空白页和路径错误问题及解决方法
2019/06/26 Javascript
vue父子模板传值问题解决方法案例分析
2020/02/26 Javascript
原生JS实现相邻月份日历
2020/10/13 Javascript
Django实现分页功能
2018/07/02 Python
python对象与json相互转换的方法
2019/05/07 Python
python中time库的实例使用方法
2019/10/31 Python
Python3 shutil(高级文件操作模块)实例用法总结
2020/02/19 Python
HTML5 Canvas鼠标与键盘事件demo示例
2013/07/04 HTML / CSS
深入解析HTML5使用SVG图像时的viewBox属性用法
2015/09/02 HTML / CSS
美国美发品牌:Bumble and Bumble
2016/10/08 全球购物
软件生产职位结构化面试主要考察要素及面试题库
2015/06/12 面试题
硕士研究生个人求职信
2013/12/04 职场文书
保密协议书范本
2014/04/22 职场文书
人力资源管理专业求职信
2014/07/23 职场文书
技术员岗位职责范本
2015/04/11 职场文书
立案决定书范文
2015/06/24 职场文书
课程设计感想范文
2015/08/11 职场文书
小学感恩主题班会
2015/08/12 职场文书
Keras在mnist上的CNN实践,并且自定义loss函数曲线图操作
2021/05/25 Python
angular4实现带搜索的下拉框
2022/03/25 Javascript