神奇运算符

每一门编程语言的设计都离不开运算符,我们写的每一行代码基本也少不了它们,这篇文章就让我们一起来了解一下这个无处不在的小伙伴的应用和小技巧吧~~

~ 按位取反

字符串查找

写JS的时候我们查找字符串时经常这么写判断字符串是否存在特定字符:

if (str.indexOf('a') != -1) {
    ...
}

这边其实可以利用~的一个小技巧,因为~-1 = 0,上面的这个判断我们可以简单用~ 进行替换:

if (~str.indexOf('a'))
    ...
}

看起来比 != 有趣多了~~

取整

正数像下取整我们用的最多的应该是类似这样:

var a = 2.3;
var b = Math.floor(a);

其实用~也可以很完美的替换整数向下取整:

var a = 2.3;
var b = ~~a;

&& 与 ||

这两兄弟基本上经常都会在一起被看到,所以这边也一起介绍一下它们。

var result; 

if status == 1) {
    result = 'Andy'
} 
else if(status == 2){ 
    result = 'Tom';
}
else { 
    result = 'John';
}

上面这种if else的代码我们用到的不能再多了。代码当然完全没有问题,看起来也很直观,如果条件多了我们也可以用switch替换,这应该是我们用的最多的方式,可读性也很好。但是我们这里思考一下是否用&& 与 || 也能达到一样的效果呢?

var result = (status == 1 && 'Andy') || 
    (status == 2 && 'Tom') || 'John';

上面这样一简单的语句作用就和前面的if else效果一样,让我不得不惊叹这对兄弟的强大。当然这也是以牺牲可读性为代价的,所以在写类似这样的代码时,简单的注释还是需要的。

感受了上面这种简洁的办法之后,本来以为应该没有办法用更少的字符达到一样的效果了吧。

但是答案是否定的,下面这条语句用各少的字符做到了一样的效果:

var result = {'1': 'Andy', '2': 'Tom'}[status] || 'John';

当JS用上位运算,原来也可以这么酷!

当然了,比起上面这些用的相对少之外,大家用的最多的无非是利用“短路”原理做一些更简单的判断。

所以这边还是顺带提及一下平常用的比较多的。

判断变量是否定义过了:

var test = test || '1';

平常的简单条件判断:

if (a === 'Andy'){ 
    console.log ('hello ' + a);
}

一般也简单用&&替换:

    a === 'Andy' && console.log ('hello ' + a);

好吧,我们最常用到的&& 与 || 两兄弟就先简单介绍到这里了。

^ 运算符

写一些逻辑性的代码时经常要用到两数交换,一般都这样写:

var a = 1, b = 2, temp;

temp = a;
a = b;
b = temp;

大一那时候不知道^也可以做两数交换,当第一次看到原来不需要额外参数也可以交换两个数字的时候也着时感叹了一下异或的神奇~

var a = 1, b = 2;

a = a ^ b;
b = b ^ a;
a = a ^ b;

简单的证明一下上面的代码:

为直观一点方便证明让 aa = a, bb = b

// a = a ^ b
a = aa ^ b  

// b = b ^ a
b = aa
  = aa ^ 0
  = aa ^ (bb ^ bb)
  = bb ^ (aa ^ bb)
  = bb ^ a   

// a = a ^ b
a = bb
  = bb ^ 0
  = bb ^ (a ^ a)
  = a ^ (bb ^a)
  = a ^ b

说到这里不得不提到一个经常被问到的面试题:在一个n - 1 的数组中不重复分布着1 ~ n 这n个数字,找出不在数组中的那个数字是啥?

估计回答最多的是用一个标记数组,然后循环一遍标记一遍。这个题目O(n)的时间效率无可厚非,那空间上怎么优化呢?

后来有人提出一种办法优化空间,把1 - n都加起来减去 n - 1 的数组的和 就得到要找的数了,非常好的办法,也不再需要O(n)的标记数组了。

除了这种办法,还有别的吗? 异或一样可以告诉我们答案,利用亦或的结合律,把n -1 数组中的所有数字异或再与 1~n 异或就得到答案了,简单证明下:

为了简单证明我们假设arr[1] = 1, arr[2] = 2, 以此类推。
a = (arr[1] ^ arr[2] ... ^ arr[n-1]) ^ (1 ^ 2 ... ^ n - 1 ^ n)
  = (arr[1] ^ 1) ^ (arr[2] ^ 2) ... ^ (arr[n-1] ^ n-1) ^ n
  = 0 ^ 0 .. ^ 0 ^ n
  = n

像好多找什么数组中重复的数字啊什么的,一样的道理可以用异或。

扯的有点远了。。。回到主题继续。

其他好玩的运算符

刚刚说到正整数 ~~ 可以向下取整,其实除了这个,还有好多办法:

var a = 2.3, b = 2.3, c = 2.3;

a = a >> 0;
b = b << 0;
c = c | 0;

说到这个,突然像到上面的代码可以做字符串转数字的方法,我们一般的写法都是:

var a = '100';
a = a - '0';

或者这样:

var a = '100';
parseInt(a, 10)

其实可以更简单的写成这样

+"100"

// 正整数
"100" | 0
"100" >> 0
"100" << 0

位运算符还有一些运算上经常用到的小技巧:

num >> 1  // 取半,偶数
num << 1  // 2倍
num & 1   // 奇偶判断

好吧,就先简单介绍到这里了,运算符还有非常多好玩的值得挖掘,熟悉运算符,能让我们写出更短更漂亮的代码~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏lonelydawn的前端猿区

lambda+reduce的一句艰深代码

一句话一脸懵逼 某天晚上看到一句lambda+reduce 组合的代码,看的头都炸了,愣是没看懂,不过也可能因为稀疏的脑神经经过一天的摧残已经运转不动了,这两天...

1798
来自专栏coder修行路

《深入理解计算机系统》阅读笔记--信息的表示和处理(上)

1663
来自专栏java一日一条

Python开发的10个小贴士

下面是十个Python中很有用的贴士和技巧。其中一些是初学这门语言常常会犯的错误。

442
来自专栏小李刀刀的专栏

容易被误解的overflow:hidden

为了页面的健壮性,我们常常需要使用overflow:hidden。有时候是为了防止布局被撑开,有时候是为了配合其它规则实现文字截断,还有时候纯粹是为了创建块级上...

35511
来自专栏程序员互动联盟

【专业文章】六种常见的HTML5写法误用(二)

四、figure元素的常见错误 figure以及figcaption的正确使用,确实是难以驾驭。让我们来看看一些常见的错误, 不是所有的图片都是figure 上...

2695
来自专栏python3

html初识

浏览器是网页运行的平台,常用的浏览器有IE、火狐(Firefox)、谷歌(Chrome)、猎豹浏览器、Safari和Opera等

923
来自专栏前端桃园

Grid布局简介

没错,这其实就是我们小时候写的小格子本本,其实它跟我们今天要讲的主题Grid布局非常类似,其实Grid布局就是它的升级加强版。

1364
来自专栏移动端周边技术扩展

关于CocoaAsyncSocket中的tag值问题

771
来自专栏五分钟学算法

看完动画你还会不懂 快速排序么

由于LeetCode上的算法题很多涉及到一些基础的数据结构,为了更好的理解后续更新的一些复杂题目的动画,推出一个新系列 -----《图解数据结构》,主要使用动画...

875
来自专栏更流畅、简洁的软件开发方式

帮助文档的数据库结构

  自然框架一直没有完整的帮助文档,只是有几个简单的示例。这个就是差距呀,那么帮助文档要怎么写呢?有工具可以自动生成,但是总感觉自动生成的一点都不好用,自己都看...

1999

扫码关注云+社区