【js技巧】~(按位非)运算符的妙用
今天在reivew部门牙套姐MM的代码的时候,有点小心得,给大家分享。我们常常说到,“学以致用”,但我发现自己却很少能真正做到。《javascript高级程序设计》即大家常说的“红宝书”,我也经常看,可是一些技巧还是要在实战中总结出来的。就比如今天将的这个~不起眼的一元运算符,学名“按位非”,在书的第三章中也有详细的介绍:
~:按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。
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);
}
啊!对啊!就是这里!!!是不是有种饼姐(部门同事:彦欣MM)所说的豁然开朗,XX大哥所说的醍醐灌顶,我所说的茅塞顿开的赶脚呢??
现在看来,我以前在对indexOf判断时候的写法,简直弱爆了,含泪上码:
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
// >= cost time:105 循环次数: 100000
//--------------------------------------------------------------------------------//
【更新 2013.10.27 17:24】感谢4楼@ joe-cn 同学的回复和建议,让我对这种写法有了新的认识,测试数据也更新下,原来的测试代码在分割线上面不变。代码如下:
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】通过修改后的测试,我们可以发现,“按位非”这中写法也许并非是效率最高的,表现最好的居然是我以前常用的写法,采用比较运算符。这确实让我很吃惊。有时候,人往往容易被常识,表象所迷惑,但亲自去尝试后,或许会有不一样的发现或得出其他的结果。今天,我算吸取教训了。
在评论中,同学们都比较反对这种非常见的写法,毕竟这些技巧可能会给阅读代码的同学造成困扰。如果不知道原理的话,甚至让人费解。或许,直接用一些简单的逻辑和常见的运算符,会是更好的选择?你们觉得呢?
因此平时写代码的时候,用哪种写法都可以。但是希望我们能将这些技巧记住,关键时刻或许就能派上用场。
【js技巧】~(按位非)运算符的妙用的更多相关文章
- js按位运算符及其妙用
大多数语言都提供了按位运算符,恰当的使用按位运算符有时候会取得的很好的效果. 在我看来按位运算符应该有7个: 1.& 按位与 &是二元运算符,它以特定的方式的方式组合操作数中对应的位, ...
- JS按位非(~)运算符与~~运算符的理解分析
按位非运算符,简单的理解就是改变运算数的符号并减去1,当然,这是只是简单的理解能转换成number类型的数据. 那么,对于typeof var!==”number”的类型来说,进行运算时,会尝试转化成 ...
- js中得~~是什么意思/JS按位非(~)运算符与~~运算符的理解分析
其实是一种利用符号进行的类型转换,转换成数字类型 ~~true == 1 ~~false == 0 ~~"" == 0 ~~[] == 0 ~~undefined ==0 ~~!u ...
- JS技巧
2016-08-09 200多个js技巧代码(Down) word下载 200多个js技巧代码 目录 1.文本框焦点问题... 6 2.网页按钮的特殊颜色... 6 3.鼠标移入移出时颜色变化... ...
- js中的等值运算符(抽象相等==与严格相等===的区别)
js中的等值运算符 js中的相等分为抽象相等和严格相等,他们有什么区别呢. 在说具体算法前,先提下JS数据类型,JS数据类型分为6类:Undefined Null String Number Bool ...
- js经典试题之运算符的优先级
js经典试题之运算符 1.假设val已经声明,可定义为任何值.则下面js代码有可能输出的结果为: console.log('Value is ' + (val != '0') ? 'define' : ...
- 提升开发幸福感的10条JS技巧
鱼头总结一些能够提高开发效率的JS技巧,这些技巧很实用,觉得挺好,想推荐给大家,所以有了这篇文章. 生成随机UID const genUid = () => { var length = 20 ...
- JS中的各类运算符
2020-04-15 JS中的各类运算符 // 假设有如下代码,那么a(10)的返回结果是?( ) function a(a) { a^=(1<<4)-1; return a; } // ...
- 你应该了解的25个JS技巧
目录 1. 类型检查小工具 2. 检查是否为空 3. 获取列表最后一项 4. 带有范围的随机数生成器 5. 随机 ID 生成器 6. 创建一个范围内的数字 7. 格式化 JSON 字符串,string ...
随机推荐
- 解决C# WinForm Graphics绘制闪烁问题
不直接使用form的CreateGraphics创建Graphics进行绘制,可以先在Form上面放一个需要大小的PictureBox,再创建一个同大小的Bitmap,将这个Bitmap设置为Pict ...
- 高性能的JavaScript--数据访问(1)
写在前面 数据存储在哪里,关系到代码运行期间数据被检索到的速度.在JavaScript中,此问题相对简单,因为数据存储只有少量方式可供选择.正如其他语言那样,数据存储位置关系到访问速度.在JavaSc ...
- artTemplate-master的应用
刚开始,在没有使用这个模板之前,一致都是后台返回一个json的字符串,来在前端自己拼接字符串,不但麻烦,而且费时费力,而且还有时候经常拼接错误!导致了工作效率的延长 js模板的使用 <scrip ...
- 【Java 新建项目】使用程序对新项目的各个实体 创建Dao、DaoImpl、Service、ServiceImpl层的文件
首先给出基本Dao层代码: GenericDao.java package com.agen.dao; import java.io.Serializable; import java.util.Co ...
- linux內核輸出soft lockup
創建的內核線程長期佔用cpu,一直內核認為線程soft lockup,如無法獲取自旋鎖等:因此線程可適度調用schdule(),以進行進程的調度:因為kwatchdog的執行級別低,一直得不到執行 [ ...
- 第二天ci项目规划 数据库设计
第二天ci项目规划 数据库设计 商品 + 用户 + 订单 数据库设计思想和方法 关于商品品牌 ,分类 ,属性 如何表示 用一个字段 还是再设计一张表 品牌和商品 是一种信息 还是两种信息 一张表一般只 ...
- UE4 AI BehaviorTree 各个节点执行顺序总结
一个游戏DEMO的AI部分 用到行为树组件如上 主要说一下这两个组件 一个装饰(类似过滤器) 一个服务(代码逻辑与Blackboard交互) Service分为 大碰撞 和 小碰撞 两个碰撞范围, 大 ...
- phpcms文章点击量统计方法
phpcms用户广大,很好用,很傻瓜.设计思路也很好,对cms的常见功能都有设计,可以作为自己开发的参考. 最近看了下phpcms的源码关于文章点击量统计的这块,自己记录下. 默认文章点击量显示的位置 ...
- 基于java平台的常用资源整理
这里整理了基于java平台的常用资源 翻译 from :akullpp | awesome-java 大家一起学习,共同进步. 如果大家觉得有用,就mark一下,赞一下,或评论一下,让更多的人知道.t ...
- PHP基础面试题
1.PHP的意思? 答:PHP是一个基于服务端来创建动态网站的脚本语言,您可以用PHP和HTML生成网站主页 2.谈谈asp,php,jsp的优缺点? 答:ASP全名Active Server Pag ...