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 相关文章推荐
指定位置如果有图片显示图片,无图片显示广告的JS
Jun 05 Javascript
javascript中使用css需要注意的地方小结
Sep 01 Javascript
js创建对象的几种常用方式小结(推荐)
Oct 24 Javascript
理清apply(),call()的区别和关系
Aug 14 Javascript
Javascript写入txt和读取txt文件示例
Feb 12 Javascript
jQuery动态添加可拖动元素完整实例(附demo源码下载)
Jun 21 Javascript
js无法获取到html标签的属性的解决方法
Jul 26 Javascript
Javascript在IE和Firefox浏览器常见兼容性问题总结
Aug 03 Javascript
JavaScript实现水平进度条拖拽效果
Jan 18 Javascript
vue中将网页打印成pdf实例代码
Jun 15 Javascript
在vue和element-ui的table中实现分页复选功能
Dec 04 Javascript
在Vue中使用Echarts实例图的方法实例
Oct 10 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 8小时时间差的解决方法小结
2009/12/22 PHP
帝国cms目录结构分享
2015/07/06 PHP
PHP邮件群发机实现代码
2016/02/16 PHP
PHP获取用户访问IP地址的5种方法
2016/05/16 PHP
php下载远程大文件(获取远程文件大小)的实例
2017/06/17 PHP
laravel Validator ajax返回错误信息的方法
2019/09/29 PHP
javaScript NameSpace 简单说明介绍
2013/07/18 Javascript
鼠标移入移出事件改变图片的分辨率的两种方法
2013/12/17 Javascript
JQuery与JS里submit()的区别示例介绍
2014/02/17 Javascript
jquery获取颜色在ie和ff下的区别示例介绍
2014/03/28 Javascript
javascript去除字符串中所有标点符号和提取纯文本的正则
2014/06/07 Javascript
jQuery的Scrollify插件实现滑动到页面下一节点
2015/07/05 Javascript
ionic实现底部分享功能
2017/05/11 Javascript
详解.vue文件中监听input输入事件(oninput)
2017/09/19 Javascript
详解vue-meta如何让你更优雅的管理头部标签
2018/01/18 Javascript
html2canvas属性和使用方法以及如何使用html2canvas将HTML内容写入Canvas生成图片
2020/01/12 Javascript
JS数组方法concat()用法实例分析
2020/01/18 Javascript
vue中音频wavesurfer.js的使用方法
2020/02/20 Vue.js
[01:10:27]DOTA2-DPC中国联赛正赛 SAG vs XG BO3 第二场 3月5日
2021/03/11 DOTA
Python语言的面相对象编程方式初步学习
2016/03/12 Python
python实现百万答题自动百度搜索答案
2018/01/16 Python
Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
2019/07/31 Python
Django发送邮件和itsdangerous模块的配合使用解析
2019/08/10 Python
python如何遍历指定路径下所有文件(按按照时间区间检索)
2020/09/14 Python
全球才华横溢工匠的家居装饰、珠宝和礼物:NOVICA
2021/01/22 全球购物
法国春天百货官网:Printemps.com
2020/06/29 全球购物
什么是抽象
2015/12/13 面试题
应届毕业生通用的自荐书范文
2014/02/07 职场文书
《我的信念》教学反思
2014/02/15 职场文书
运动会搞笑广播稿
2014/10/14 职场文书
个人欠款协议书范本2014
2014/11/02 职场文书
2014年政协工作总结
2014/12/09 职场文书
毕业生就业推荐表导师评语
2014/12/31 职场文书
星际争霸:毕姥爷vs解冻01
2022/04/01 星际争霸
微信小程序APP的事件绑定以及传递参数时的冒泡和捕获
2022/04/19 Javascript
错误码NET::ERR_CERT_DATE_INVALID证书已过期解决方法?
2022/07/07 数码科技