Messing with Javascript
by
, 01-22-2017 at 06:15 AM (10798 Views)
Hey all,
I've been fiddling with JavaScript and decided to share a neat little thing (its completely useless).
Finished Code
Now for the break down -Code:console.log(+[[-~[]<<~[]][+[]]+[]][+[]][++[[]][+[]]+[+[]]]); //Prints 8
Pre-note - I use this function while playing with variables. It outputs the value and type of a variable. (The counter is to force the developer console to display each seperately)
Code:var counter = 0; function pLog(arg) { console.log(++counter + ": " + typeof(arg) + "(" + arg + ")"); }
First thing you have to understand is that you can cast a string to a number be using a math operator on it.
E.g.
Notice the +"7".Code:pLog("7"); //Outputs string(7) pLog(+"7"); //Outputs number(7)
This takes the string "7" and converts it to the number 7.
This trick works with several mathematical operators. But + doesn't modify the actual value while converting it.
The next thing to understand is you can convert some other types of variables, not just strings, to numbers in the same way.
E.g.
Code:var x = false; var y = []; var z = {}; var q = function() {}; pLog(x); //boolean(false) pLog(+x); //number(0) pLog(y); //object(0) pLog(+y); //number(0) pLog(z); //object([object Object]) pLog(+z); //number(NaN) pLog(q); //function(function () {}) pLog(+q); //number(NaN)
Ok, so we know that when we use math operators on an empty array it outputs 0.
Operators
There are two special operators in the original code: "~" and "<<". These are called Bitwise Operators.
The~
operator is called the Bitwise NOT. It inverts the bits of a number.
You may notice that this operator is the equivalent of the math function -(N + 1)Code:var x = 10; pLog(x); //number(10) pLog(~x); //number(-11)
The<<
is the Left Shift operator. It shifts a number in binary representation N bits to the left, shifting in zeroes from the right.
If you don't understand any of this, I'd recommend researching binary numbers.
The decimal number 3 is represented asCode:var x = 3; pLog(x); //number(3) pLog(x<<3); //number(24)"11"
in binary.
If you shift that to the left by 3 places, padding with zeroes that'd be binary"11000"
which is 24!
Breaking down the actual code
First thing to do is make it a bit more readable -
Ok so we know that when we use math operators on an empty array it gives 0Code:+[[ -~[] << ~[] ][+[]] + []][ +[] ][ ++[[]][ +[] ] + [+[]] ]
We also know that ~ is basically -(N + 1)
so
+[] == 0
and
~[] == ~0
~0 == -1
So we know that+[]
is zero and~[]
is negative one.
The minus before the~[]
simply changes it from a negative to a positive number (double negative).
Going through and replacing those through the code we get
Definitely looking a bit more readable.Code:+[[ 1 << -1 ][0] + []][0][ ++[[]][0] + [0] ]
Notice the++[[]][0]
If we have an array -
We know thatCode:var x = [10, 2];x[0]
will return the first value of the array.
So[[]]
is the array and[0]
returns the first value of that array (which is [], an empty array)
Since+[]
is 0 and++
is the incremental operator,++[]
gives us 1.
Definitely more readable now.Code:+[[ 1 << -1 ][0] + []][0][1 + [0]]
Onto the left shift operator:
If you run
it should output the number(-2147483648)Code:pLog(1<<-1);
If you want to understand why, read http://stackoverflow.com/questions/1...-in-javascript
So now we have
TheCode:+[[-2147483648][0] + []][0][1 + [0]][0]
returns the first value from the array, giving us -
Another important Javascript "feature" is that the + symbol isn't just a mathematical symbol.Code:+[-2147483648 + []][0][1 + [0]]
Its also used to concatenate two strings.
When you concat anything with an array it treats the array like a string
SoCode:pLog("test" + [1]); //string(test1) pLog("test" + [1,2]); //string(test1,2) pLog([1,4] + [5, 7]) //string(1,45,7)-2147483648 + []
actually just converts -2147483648 into the string "-2147483648".
Notice the last part of the code:Code:+["-2147483648"][0][ 1 + [0]][1 + [0]]
If it were[1 + 0]
that would evaluate to 1.
However, because[0]
is treated as the string "0", it is concatenated onto the number 1. (Have a read through this link if you'd like)
This gives us
Now theCode:+["-2147483648"][0]["10"][0]
gives us the first value of the array.
However its not the same as this
because in that cause the + converts the string to a number instantly.Code:+"-2147483648"["10"]
Another neat trick is that you can get the Nth character of a string by accessing it as if it were an array.
However, in Javascripts arrays aren't really arrays, they're objects.Code:var x = "testing123"; pLog(x[3]); //string(t)
When you're accessing an object property you can do it two different ways
The second method is useful when you're trying to access a dynamiclly named property on an object.Code:var x = { randomText: "Hi!", randomText2: "Hello!" }; pLog(x.randomText); pLog(x["randomText2"]);
But since arrays are actually objects
Please note x and y are not the same.Code:var x = [ "test", "test2", "test3" ]; var y = { 0: "test", 1: "test2", 2: "test3" }; pLog(x); //object(test,test2,test3) pLog(y); //object([object Object]) pLog(x[1]); //string(test2) pLog(y[1]); //string(test2)
So our current code was
We know that theCode:+["-2147483648"][0]["10"][0]
returns the string and the["10"]
returns the 10th character of the string.
Note: either[10]
or["10"]
will work
Giving us
Now all that's left is the conversion to a number and we get...Code:+"8"
Ta Da!Code:8
More reading -
http://stackoverflow.com/questions/7...-the-string-10
https://developer.mozilla.org/en/doc...wise_Operators
http://www.binaryhexconverter.com/bi...imal-converter