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 相关文章推荐
JavaScript的public、private和privileged模式
Dec 28 Javascript
使用 Node.js 做 Function Test实现方法
Oct 25 Javascript
jquery实现简单易懂的图片展示小例子
Nov 21 Javascript
jQuery判断div随滚动条滚动到一定位置后停止
Apr 02 Javascript
简介AngularJS中使用factory和service的方法
Jun 17 Javascript
js判断上传文件后缀名是否合法
Jan 28 Javascript
微信小程序 wxapp内容组件 icon详细介绍
Oct 31 Javascript
通过Ajax使用FormData对象无刷新上传文件方法
Dec 08 Javascript
微信小程序 wx.uploadFile在安卓手机上面the same task is working问题解决
Dec 14 Javascript
jQuery实现ajax的嵌套请求案例分析
Feb 16 jQuery
JS实现灯泡开关特效
Mar 30 Javascript
微信小程序 WeUI扩展组件库的入门教程
Apr 21 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脚本执行卡住的问题
2016/12/27 PHP
PHP preg_match实现正则表达式匹配功能【输出是否匹配及匹配值】
2017/07/19 PHP
PHP进阶学习之类的自动加载机制原理分析
2019/06/18 PHP
Javascript学习笔记6 prototype的提出
2010/01/11 Javascript
Javascript 中的 call 和 apply使用介绍
2012/02/22 Javascript
jQuery滚动加载图片效果的实现
2013/03/06 Javascript
简单漂亮的js弹窗可自由拖拽且兼容大部分浏览器
2013/10/22 Javascript
js字符串转成JSON
2013/11/07 Javascript
jQuery分别获取选中的复选框值的示例
2014/06/17 Javascript
jquery append()方法与html()方法的区别及使用介绍
2014/08/01 Javascript
JavaScript获取表单enctype属性的方法
2015/04/02 Javascript
JavaScript操作XML文件之XML读取方法
2015/06/09 Javascript
简介JavaScript中的setTime()方法的使用
2015/06/11 Javascript
JavaScript实现数组随机排序的方法
2015/06/26 Javascript
学习JavaScript设计模式之策略模式
2016/01/12 Javascript
快速解决Canvas.toDataURL 图片跨域的问题
2016/05/10 Javascript
Vue.js:使用Vue-Router 2实现路由功能介绍
2017/02/22 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
基于IView中on-change属性的使用详解
2018/03/15 Javascript
js正则表达式校验指定字符串的方法
2018/07/23 Javascript
layui中使用jquery控制radio选中事件的示例代码
2018/08/15 jQuery
用Electron写个带界面的nodejs爬虫的实现方法
2019/01/29 NodeJs
javascript面向对象三大特征之继承实例详解
2019/07/24 Javascript
原生js实现ajax请求和JSONP跨域请求操作示例
2020/03/14 Javascript
谈谈我在vue-cli3中用预渲染遇到的坑
2020/04/22 Javascript
vuex存取值和映射函数使用说明
2020/07/24 Javascript
简单介绍使用Python解析并修改XML文档的方法
2015/10/15 Python
python3实现暴力穷举博客园密码
2016/06/19 Python
使用Python3制作TCP端口扫描器
2017/04/17 Python
Python 爬虫的原理
2020/07/30 Python
详解python爬取弹幕与数据分析
2020/11/14 Python
python字典与json转换的方法总结
2020/12/28 Python
豆腐の盛田屋官网:日本自然派的豆乳面膜、肥皂、化妆水、乳液等
2016/10/08 全球购物
师范生教师实习自我鉴定
2013/09/27 职场文书
企业形象策划方案
2014/05/29 职场文书
小学作文指导之如何写人?
2019/07/08 职场文书