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中的mouseleave和mouseout的区别 模仿下拉框效果
Feb 07 Javascript
关于编写性能高效的javascript事件的技术
Nov 28 Javascript
JavaScript使用键盘输入控制实现数字验证功能
Aug 19 Javascript
jQuery简单实现列表隐藏和显示效果示例
Sep 12 Javascript
自制微信公众号一键排版工具
Sep 22 Javascript
浅谈javascript中遇到的字符串对象处理
Nov 18 Javascript
bootstrap实现图片自动轮播
Dec 21 Javascript
bootstrap table 表格中增加下拉菜单末行出现滚动条的快速解决方法
Jan 05 Javascript
js随机生成一个验证码
Jun 01 Javascript
基于AngularJS实现表单验证功能
Jul 28 Javascript
jQuery中将json数据显示到页面表格的方法
May 27 jQuery
vue-cli设置publicPath小记
Apr 14 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取得一个类的属性和方法的实现代码
2011/05/22 PHP
免费手机号码归属地API查询接口和PHP使用实例分享
2014/04/10 PHP
标准PHP的AES加密算法类
2015/03/12 PHP
利用php抓取蜘蛛爬虫痕迹的示例代码
2016/09/30 PHP
PDO::prepare讲解
2019/01/29 PHP
jquery中加载图片自适应大小主要实现代码
2013/08/23 Javascript
jquery选择器大全 全面详解jquery选择器
2014/03/06 Javascript
JavaScript动态修改网页元素内容的方法
2015/03/21 Javascript
JavaScript使用RegExp进行正则匹配的方法
2015/07/11 Javascript
javascript设置页面背景色及背景图片的方法
2015/12/29 Javascript
你一定会收藏的Nodejs代码片段
2016/02/04 NodeJs
JavaScript职责链模式概述
2016/09/17 Javascript
Vue项目中quill-editor带样式编辑器的使用方法
2017/08/08 Javascript
MVVM框架下实现分页功能示例
2018/06/14 Javascript
微信小程序scroll-view实现滚动穿透和阻止滚动的方法
2018/08/20 Javascript
在vue项目中使用Jquery-contextmenu插件的步骤讲解
2019/01/27 jQuery
小程序按钮避免多次调用接口和点击方案实现(不用showLoading)
2020/04/15 Javascript
[45:44]完美世界DOTA2联赛PWL S2 FTD vs PXG 第一场 11.27
2020/12/01 DOTA
[01:48:04]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第一场 2月7日
2021/03/11 DOTA
python中字典(Dictionary)用法实例详解
2015/05/30 Python
对python多线程与global变量详解
2018/11/09 Python
对python csv模块配置分隔符和引用符详解
2018/12/12 Python
Pandas-Cookbook 时间戳处理方式
2019/12/07 Python
python的pip有什么用
2020/06/17 Python
关于h5中的fetch方法解读(小结)
2017/11/15 HTML / CSS
Evisu官方网站:日本牛仔品牌,时尚街头设计风格
2016/12/30 全球购物
意大利奢华内衣制造商:Cosabella
2017/08/29 全球购物
意大利在线眼镜精品店:Ottica Lipari
2019/11/11 全球购物
介绍一下SQL Server里面的索引视图
2016/07/31 面试题
商务考察邀请函范文
2014/01/21 职场文书
期末自我鉴定
2014/02/02 职场文书
大学生入党推荐书范文
2014/05/17 职场文书
教室标语大全
2014/06/21 职场文书
对公司的意见和建议
2015/06/04 职场文书
2016年小学端午节活动总结
2016/04/01 职场文书
java协程框架quasar和kotlin中的协程对比分析
2022/02/24 Java/Android