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的网页SELECT下拉框美化代码
Oct 28 Javascript
扩展easyui.datagrid,添加数据loading遮罩效果代码
Nov 02 Javascript
EasyUI 中 MenuButton 的使用方法
Jul 14 Javascript
Jquery获取复选框被选中值的简单方法
Jul 04 Javascript
JavaScript实现的图像模糊算法代码分享
Apr 22 Javascript
js实现简单的可切换选项卡效果
Apr 10 Javascript
javascript实现动态导入js与css等静态资源文件的方法
Jul 25 Javascript
浅谈angularJS中的事件
Jul 12 Javascript
React Native实现进度条弹框的示例代码
Jul 17 Javascript
解决layui table表单提示数据接口请求异常的问题
Sep 24 Javascript
Vue-cli3多页面配置详解
Mar 22 Javascript
JavaScript实现网页动态生成表格
Nov 25 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中获取文件扩展名的N种方法小结
2012/02/27 PHP
PHP获取数组中指定的一列实例
2017/12/27 PHP
php实现的mongoDB单例模式操作类
2018/01/20 PHP
jquery插件 autoComboBox 下拉框
2010/12/22 Javascript
两个listbox实现选项的添加删除和搜索
2013/03/01 Javascript
基于NodeJS的前后端分离的思考与实践(二)模版探索
2014/09/26 NodeJs
jQuery原型属性和原型方法详解
2015/07/07 Javascript
全面解析Bootstrap图片轮播效果
2015/12/03 Javascript
AngularJS中的指令全面解析(必看)
2016/05/20 Javascript
基于jquery插件编写countdown计时器
2016/06/12 Javascript
JS限定手机版中图片大小随分辨率自动调整的方法
2016/12/05 Javascript
vue.js项目中实用的小技巧汇总
2017/11/29 Javascript
Angular2.0/4.0 使用Echarts图表的示例代码
2017/12/07 Javascript
vue中,在本地缓存中读写数据的方法
2018/09/21 Javascript
js图片查看器插件用法示例
2019/06/22 Javascript
构建Vue大型应用的10个最佳实践(小结)
2019/11/07 Javascript
jquery传参及获取方式(两种方式)
2020/02/13 jQuery
Vue 中使用 typescript的方法详解
2020/02/17 Javascript
浅谈vue单页面中有多个echarts图表时的公用代码写法
2020/07/19 Javascript
vue-router 按需加载 component: () =&gt; import() 报错的解决
2020/09/22 Javascript
Flexible.js可伸缩布局实现方法详解
2020/11/13 Javascript
在vue项目中封装echarts的步骤
2020/12/25 Vue.js
pycharm 使用心得(二)设置字体大小
2014/06/05 Python
python中的函数递归和迭代原理解析
2019/11/14 Python
python如何爬取网页中的文字
2020/07/28 Python
video实现有声音自动播放的实现方法
2020/05/20 HTML / CSS
复古服装:RetroStage
2019/05/10 全球购物
财务部岗位职责
2013/11/19 职场文书
商务考察邀请函范文
2014/01/21 职场文书
汽车装潢店创业计划书范文
2014/02/05 职场文书
房屋买卖协议样本
2014/11/16 职场文书
教师党员承诺书2015
2015/01/21 职场文书
同学联谊会邀请函
2019/06/24 职场文书
如何用threejs实现实时多边形折射
2021/05/07 Javascript
ElementUI实现el-form表单重置功能按钮
2021/07/21 Javascript
Java Redisson多策略注解限流
2022/09/23 Java/Android