-1

Can anybody explain me why this javascript code alerts "47" ?

var component = +((!+[] + !![] + !![] + !![] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + !![]));
alert(component);

how those brackets, plus signs, etc return 47 at the end when I execute them ?

how to write this in PHP. I understand this is something with strings, booleans, etc.. but can't understand it ?

Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 10
    Why would you want to write this in PHP? – Gordon Aug 10 '14 at 17:59
  • 3
    Try breaking it down operation by operation and figure out what each operation is doing (and have the rules of javascript implicit type conversions open while you do so). The browser console is good for this. I could do this for you, but I'm too lazy, and it's a good learning experience for you :) Plus this seems like the kind of silly exercise that would get assigned as a class assignment. – Mike Bell Aug 10 '14 at 18:00
  • 1
    In JavaScript, false + false -> 0, false + true -> 1, true + true -> 2; the arrays (in most cases) are not actually used, except to be a source expression. ![] -> false, !![] -> true, !+[] -> true. – user2864740 Aug 10 '14 at 18:01
  • 1
    ![]==0, !![]==1. adding one 7 times = 7... – dandavis Aug 10 '14 at 18:01
  • http://patriciopalladino.com/blog/2012/08/09/non-alphanumeric-javascript.html – Bergi Aug 10 '14 at 18:04

5 Answers5

1
false       =>  ![] 

true        =>  !![] 

undefined    =>  [][[]] 

NaN          =>  +[![]] 

0            =>  +[] 

1            =>  +!+[] 

2            =>  !+[]+!+[] 

10           =>  [+!+[]]+[+[]] 

Array        =>  [] 

Number      =>  +[] 

String       =>  []+[] 

Boolean      =>  ![] 

Function     =>  []["filter"] 

eval         =>  []["filter"]["constructor"]( CODE )()

window      =>  []["filter"]["constructor"]("return this")()

Just about anything javascript can be turned into incredibly hard to read crap if you use those conversions. It is stupid, but it can be done.

So take the 10 for example:

[+!+[]]+[+[]] 

This is really two components:

[+!+[]]

and

[+[]] 

This is just [1] and [0]. But if we add them together, they are cast to strings, so we get "1" + "0" which gives us "10".

For your question:

+((!+[] + !![] + !![] + !![] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + !![]));

I'll break down the 4 component:

(!+[] + !![] + !![] + !![] + [])

true + true + true + true + array

which if you run it in the console, gives you 4. The last [] does nothing for this part, but it forces the typecast to string, which is important for the next part.

Then, the next one becomes

true + true + true + true + true + true + true

which gives you 7.

So you get 4 + [] + 7, which makes "47" since the + [] + forces the typecast to string.

To do it in PHP, you could do something like:

$x = (![] + ![] + ![] + ![]) . (![] + ![] + ![] + ![] + ![] + ![] + ![]);
//$x is now 47
dave
  • 62,300
  • 5
  • 72
  • 93
  • Your native constructors are all lacking a `.constructor`. `[] !== Array` – Bergi Aug 10 '14 at 18:05
  • Also, could you please be more specific about the line in the question? The `10` example, with a bit explanation, could be easily extended to make `47` – Bergi Aug 10 '14 at 18:06
  • @olive_tree: No, it's way too early for accepting now. He should wait a bit with that and then choose the highest-quality one. – Bergi Aug 10 '14 at 18:08
  • Sure, he did comment above those- also personally I find this answer to be most clear. – olive_tree Aug 10 '14 at 18:09
  • I understood the meanings, but how to write this in PHP as a $component variable to return 47 ? – user3886199 Aug 10 '14 at 18:09
1

In JavaScript, false + false -> 0, false + true -> 1, true + true -> 2. The arrays are not used directly, except to be a source expression: ![] -> false, !![] -> true, !+[] -> true, and number + [] -> "number".

Thus we have (where t = true, f = false):

+((!+[] + !![] + !![] + !![] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + !![]));

+((t + t + t + t + []) + (t + t + t + t + t + t + t));

+((4 + []) + (7));

Now, see 4 + []? That is handled as a string concatenation after conversions, and the result is "4" so:

+(("4") + (7))

+("4" + 7)

+("47")

47

I have no idea how this particular piece would translate to PHP.

user2864740
  • 60,010
  • 15
  • 145
  • 220
1

In JS:

The JS elements:

+[]: 0
![]: true
+![]: 1
!![]: false
+!![]: 0

In PHP:

  • array() is an empty array
  • ! means "not", so it converts to true to false and vice versa as in js
  • (int) will typecast the boolean to an integer, like the + did in js.

The PHP Elements:

(int) empty(array()): 0
empty(array()): true
(int) empty(array()): 1
!empty(array()): false
(int) !empty(array()): 0

Now add it all up. Good luck.

Community
  • 1
  • 1
zeusstl
  • 1,673
  • 18
  • 19
1

There is various things need to analysis one by one, let's start:

suppose

var p = [];
console.log(typeof p) // => object (array) 
console.log(p) //=> []

Again,

var p = +[]; 
console.log(typeof p) //=> number 
console.log(p) //=> 0

Again,

var p = ![]; 
console.log(typeof p); //boolean
console.log(p); //false 

Again,

var p =   !![];
console.log(typeof p); // boolean
console.log(p); //true

Again,

var p =   !+[];
console.log(typeof p);  //boolean
console.log(p);  //true

Now

boolean true ==> 1
boolean false ==> 0 

So,

var p =  (
   !+[] + 
   !![] + 
   !![] + 
   !![] + 
   []
 );
console.log(typeof p); //string 
console.log(p); // 4 

And

var p = (
    !+[] + 
    !![] + 
    !![] + 
    !![] + 
    !![] + 
    !![] + 
    !![]
  );
console.log(typeof p); //number 
console.log(p);  // 7 

Finally:

var p = +(
 (
   !+[] + 
   !![] + 
   !![] + 
   !![] + 
   []
 ) + 

  (
    !+[] + 
    !![] + 
    !![] + 
    !![] + 
    !![] + 
    !![] + 
    !![]
  )

);
console.log(typeof p); //Number
console.log(p); //47

You can write the same in php with array, boolean ( negation !) .

Hrishikesh Mishra
  • 3,295
  • 3
  • 27
  • 33
0
+[] -> 0 //Because + converts all other javascript types to numbers
!+[] -> true //Because ! converts 0 to true
![] -> false //Empty array is true 
!![] -> true //Because ![] is false

(!+[] + !![] + !![] + !![] + []) -> true+true+true+true+""="4"

+ converts Boolean value to 1 if it is true, and 0 if it is false.`

And this is a string value,because Number+Empty object creates a string, because an Empty Object can't convert to Number it converts to a String. And as we know Number+String->String.

As a result: (!+[] + !![] + !![] + !![] + []) is the same as "4"

In the same way

(!+[] + !![] + !![] + !![] + !![] + !![] + !![]) -> true+true+true+true+true+true+true = 7 //this is a Number, because Boolean value converts to a Number: either 0 or 1    

And finally

"4"+7=47
Andranik
  • 90
  • 3