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制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法
Aug 08 Javascript
JS教程:window.location使用方法的区别介绍
Oct 04 Javascript
node.js中的fs.realpathSync方法使用说明
Dec 16 Javascript
自定义jQuery插件方式实现强制对象重绘的方法
Mar 23 Javascript
jquery实现可自动判断位置的弹出层效果代码
Oct 12 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
Apr 22 Javascript
vue中的event bus非父子组件通信解析
Oct 27 Javascript
JS散列表碰撞处理、开链法、HashTable散列示例
Feb 08 Javascript
浅谈发布订阅模式与观察者模式
Apr 09 Javascript
JavaScript命名空间模式实例详解
Jun 20 Javascript
Vue实现附件上传功能
May 28 Javascript
JS遍历树层级关系实现原理解析
Aug 31 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高级OOP技术演示
2009/08/27 PHP
php中选择什么接口(mysql、mysqli)访问mysql
2013/02/06 PHP
PHP字符串的连接的简单实例
2013/12/30 PHP
php $_SERVER windows系统与linux系统下的区别说明
2014/02/14 PHP
PHP实现获取某个月份周次信息的方法
2015/08/11 PHP
PHP页面输出时js设置input框的选中值
2016/09/30 PHP
php curl常用的5个经典例子
2017/01/20 PHP
[原创]PHP正则删除html代码中a标签并保留标签内容的方法
2017/05/23 PHP
Laravel中日期时间处理包Carbon的简单使用
2017/09/21 PHP
php实现微信和支付宝支付的示例代码
2020/08/11 PHP
JQuery实现用户名无刷新验证的小例子
2013/03/22 Javascript
各种页面定时跳转(倒计时跳转)代码总结
2013/10/24 Javascript
javascript中parseInt()函数的定义和用法分析
2014/12/20 Javascript
JS实现同时搜索百度和必应的方法
2015/01/27 Javascript
javascript实现动态导入js与css等静态资源文件的方法
2015/07/25 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
2016/06/06 Javascript
JavaScript拖动层Div代码
2017/03/01 Javascript
详解Require.js与Sea.js的区别
2018/08/05 Javascript
如何优雅地在vue中添加权限控制示例详解
2019/03/07 Javascript
JS常见内存泄漏及解决方案解析
2020/05/30 Javascript
Vue $emit()不能触发父组件方法的原因及解决
2020/07/28 Javascript
为Python的Tornado框架配置使用Jinja2模板引擎的方法
2016/06/30 Python
浅谈Django学习migrate和makemigrations的差别
2018/01/18 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
2020/04/14 Python
Python unittest discover批量执行代码实例
2020/09/08 Python
澳大利亚正品化妆品之家:Cosmetic Capital
2017/07/03 全球购物
英国知名小木屋定制网站:Tiger Sheds
2020/03/06 全球购物
上课说话检讨书大全
2014/01/22 职场文书
乡村文明行动实施方案
2014/03/29 职场文书
销售提升方案
2014/06/07 职场文书
国际会计专业求职信
2014/08/04 职场文书
贵阳市党的群众路线教育实践活动党(工)委领导班子整改方案
2014/10/26 职场文书
工会积极分子个人总结
2015/03/03 职场文书
培训感想范文
2015/08/07 职场文书
写作技巧:怎样写好一份优秀工作总结?
2019/08/14 职场文书
MySQL中distinct与group by之间的性能进行比较
2021/05/26 MySQL