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实现的距离现在多长时间后的一个格式化的日期
Oct 29 Javascript
juqery 学习之三 选择器 层级 基本
Nov 25 Javascript
setTimeout和setInterval的区别你真的了解吗?
Mar 31 Javascript
jquery无刷新验证邮箱地址实现实例
Feb 19 Javascript
JavaScript设计模式之抽象工厂模式介绍
Dec 28 Javascript
适用于javascript开发者的Processing.js入门教程
Feb 24 Javascript
AngularJS入门教程之AngularJS模型
Apr 18 Javascript
Js调用Java方法并互相传参的简单实例
Aug 11 Javascript
js模拟支付宝密码输入框
Apr 11 Javascript
在vue中使用v-bind:class的选项卡方法
Sep 27 Javascript
vue-cli3 项目从搭建优化到docker部署的方法
Jan 28 Javascript
解决Vue 给mapState中定义的属性赋值报错的问题
Jun 22 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中使用sockets:从新闻组中获取文章
2006/10/09 PHP
Smarty结合Ajax实现无刷新留言本实例
2007/01/02 PHP
PHP日期函数date格式化UNIX时间的方法
2015/03/19 PHP
php单例模式的简单实现方法
2016/06/10 PHP
语义化 H1 标签
2008/01/14 Javascript
javascript json 新手入门文档
2009/12/03 Javascript
jQuery选择头像并实时显示的代码
2010/06/27 Javascript
JavaScript 事件系统
2010/07/22 Javascript
JavaScript高级程序设计 客户端存储学习笔记
2011/09/10 Javascript
P3P Header解决Cookie跨域的问题
2013/03/12 Javascript
JS实现随机化快速排序的实例代码
2013/08/01 Javascript
火狐下table中创建form导致两个table之间出现空白
2013/09/02 Javascript
解析offsetHeight,clientHeight,scrollHeight之间的区别
2013/11/20 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
2014/06/15 Javascript
JavaScript动态修改网页元素内容的方法
2015/03/21 Javascript
原生js实现类似弹窗抖动效果
2015/04/02 Javascript
javascript cookie用法基础教程(概念,设置,读取及删除)
2016/09/20 Javascript
Vue如何从1.0迁移到2.0
2017/10/19 Javascript
浅谈mvvm-simple双向绑定简单实现
2018/04/18 Javascript
详解React Native 屏幕适配(炒鸡简单的方法)
2018/06/11 Javascript
微信jssdk踩坑之签名错误invalid signature
2020/05/19 Javascript
JavaScript 防抖和节流遇见的奇怪问题及解决
2020/11/20 Javascript
python使用socket远程连接错误处理方法
2015/04/29 Python
Python selenium 三种等待方式详解(必会)
2016/09/15 Python
python 实现对文件夹中的图像连续重命名方法
2018/10/25 Python
Pycharm取消py脚本中SQL识别的方法
2018/11/29 Python
感恩教育活动总结
2014/05/05 职场文书
国旗下讲话演讲稿
2014/05/08 职场文书
人事行政经理岗位职责
2014/06/18 职场文书
大一新生期末自我评价
2014/09/12 职场文书
教师法制教育培训学习心得体会
2016/01/14 职场文书
《海上日出》教学反思
2016/02/23 职场文书
php 解析非标准json、非规范json
2021/04/01 PHP
浅谈JS的二进制家族
2021/05/09 Javascript
ORACLE数据库应用开发的三十个注意事项
2021/06/07 Oracle
Python中with上下文管理协议的作用及用法
2022/03/18 Python