岁月如歌

用开放的心态,打造专业的人生。

利用位反操作来简化 indexOf 判断

with 16 comments

补码

在计算机系统中,数值用补码来表示。任何数值 n 的位反等于 -(n + 1):

~n === -(n + 1)

可以得到:

~9 === -10
~8 === -9
~1 === -2
~0 === -1
~-1 === 0
~-2 === 1
~-9 === 8
~-10 === 9

很明显,只有 ~-1 才等于 0. 对非 -1 值取反永远不为 0.

String#indexOf

String 的 indexOf 方法,找到时,返回自然数;没找到,则返回 -1. 常见代码:

if (str.indexOf('sub') !== -1) {
  // code
}

利用位反操作,可简化为:

if (~str.indexOf('sub')) {
  // code
}

更普适的规律是:

  1. n !== -1 可简化为 ~n
  2. n === -1 可简化为 !~n

Array#indexOf

涉及状态判断时,很容易写出以下代码:

if (statusCode === 301 || statusCode === 302) {
 // code
}

利用 Array#indexOf, 上面的代码可简化成:

if ([301, 302].indexOf(statusCode) !== -1) {
  // code
}

用位反操作,可进一步简化:

if (~[301, 302].indexOf(statusCode)) {
  // code
}

类似的,可以:

if (~["loaded", "complete"].indexOf(readyState)) {
  // code
}

写在最后

一般来说,位反等简化方式有损可读性。可读性有两方面:

  1. 自己的代码给他人看。这时代码的通俗易懂很重要,尽量少用奇技淫巧。
  2. 自己看他人的代码。这时要让自己的知识面尽可能广,包括吃透各种奇技淫巧。

从学习的角度讲,吃透一些奇技淫巧,经常能深入到语言的部分底层细节,非常有益处。

还有一个不容忽视的现象:奇技淫巧有阶段性。好的技巧,在小圈子流行后,有可能会慢慢被大众接受,也就不再是奇技淫巧了,比如 (function(){ /* code */ })().

总之,技巧不怕多,权衡去用就好。

Advertisements

Written by lifesinger

September 30, 2011 at 10:44

Posted in Articles

16 Responses

Subscribe to comments with RSS.

  1. 这样写的确是要流行起来以后才有可读性…

    Justice

    September 30, 2011 at 10:52

  2. 受教

    czy88840616

    September 30, 2011 at 11:17

  3. 太赞了,我一直觉得 “== -1” 太丑了~ 😀

    oldj

    September 30, 2011 at 11:34

  4. 说真的,确实觉得很奇技淫巧….能不能流行就很难说了

    whiletrue

    September 30, 2011 at 11:51

  5. 常用的还有 ~~ ,相当于parseInt

    simamy

    September 30, 2011 at 12:04

  6. …..在firefox 7下测试的的时候~[301, 302].indexOf(301) ~[301, 302].indexOf(302)分别返回-1 -2.. 这。。还要加!!。。。

    atr

    September 30, 2011 at 16:28

  7. 貌似把 取反(~, 位运算符) 和 补码 概念弄混了…

    ~n = -(n+1)
    是对位取反操作, 不是 补码…., 补码不是这样运算…

    🙂

    myhere

    September 30, 2011 at 20:57

    • 感谢指正,笔误了。原文已修正为 “任何数值 n 的位反等于 -(n + 1)” 。

      lifesinger

      October 1, 2011 at 08:00

  8. org的域名不再用了?以后就是这个了?

    xiangzhuyuan

    October 7, 2011 at 10:42

  9. JK

    October 7, 2011 at 12:50

  10. 为什么要用 === -1 呢?我一直都是用 = 0 啊。我才来不关心找不到的是不是 -1 ,不同语言的实现可以不一样,但是找到的语义是非常确定的——给我返回一个位于 [0, length – 1) 区间的数。大多数语言的实现都不会返回一个 [length, +Infinite] 的数来表示找不到的,所以我只要比较返回的数跟 0 的关系就可以了。

    cathsfz

    October 8, 2011 at 00:52

  11. […] 利用位反操作来简化 indexOf 判断 […]

  12. […] 利用位反操作来简化indexOf判断 […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s