21

According to this post, run the following codes

> ~function () { console.log('foo');}()
  foo
  -1

As we all know, the return value of the above anonymous function is undefined. Why ~undefined is -1? I couldn't find any similar question.

Ryan Fung
  • 1,893
  • 8
  • 35
  • 57
zangw
  • 33,777
  • 15
  • 127
  • 153

3 Answers3

22

~ is bitwise NOT. It uses ToInt32 to convert the argument to a number. ToInt32 is defined as:

  1. Let number be ToNumber(argument).
  2. ReturnIfAbrupt(number).
  3. If number is NaN, +0, −0, +∞, or −∞, return +0.
    ...

In turn, ToNumber(undefined) returns NaN, so according to step 3, ToInt32 returns 0.

And ~0 is -1.

Felix Kling
  • 705,106
  • 160
  • 1,004
  • 1,072
  • 1
    Could you please points to where the standard says that *"operators are converted to signed 32-bit integers in two's complement format"* link to `ToInt32` (I am not questioning your answer, I am just curious)? – Holt Dec 18 '15 at 07:52
  • @Holt: I did link to the definition of `ToInt32`. Did you want a link to the spec of the NOT operator? – Felix Kling Dec 18 '15 at 07:56
  • Yes, I found it [here](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-bitwise-not-operator) - The standard is far more explicit that the doc on developer.mozilla.org, I think it could be a good idea to add a link (or even quote) the standard for the `NOT` operator in your post. – Holt Dec 18 '15 at 07:59
  • all bitwise operators in javascript are done using (mainly) signed 32bit integers - I say mainly, because RHS of <> and both LHS and RHS of >>> are unsigned 32bit – Jaromanda X Dec 18 '15 at 08:01
  • @JaromandaX I was asking because (for me) the quote from `developer.mozilla.org` is a bit equivocal, but the standard clearly points to `ToInt32`. – Holt Dec 18 '15 at 08:07
7

every thing that cannot be represented in bits in JS for example "undefined, NaN" is treated a 0 or 0000000000000b for the ~ operator since it converts the operand into an signed integer see @felixkling answer for more details on this and since the operation ~ is BITwise not or 1s complement which flips the bits so the statement results in 111111111111b as a sequence of 1 and when dealing in numbers on binary level the MSB(most significant bit) is treated as a sign so when converting all the 0s to 1s it results in decimal value of -1 try ~0 for instance. and use this code to get the binary representation of a number (-3 >>> 0).toString(2))

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
Minato
  • 3,785
  • 1
  • 18
  • 27
2

Apparently the bit representation of undefined is all 0s. This can be seen if by the following: undefined | 0 which evaluates to 0. Because of this we know that undefined's bit representation is all zeros.

If we now filp all bits (wich is exactly what ~ does) we get all 1s which is the representation of -1.

All this works because of javascript's type cohersion

wastl
  • 2,563
  • 9
  • 25