For an online challenge, I've deobfuscated some code to this:
A = (0)['constructor']['constructor']
From what I've tried, this function takes some code as parameter and puts it in the body of an anonymous function and returns it.
A = (0)['constructor']['constructor']
console.log(A)
console.log(A('return 9'))
console.log(A('return 9')())
However, I don't understand this syntax and how the function is created. What's happening behind the scene ?
There's a surprising amount going on here, so I'll try to break it down into steps.
0
is a primitive number. Primitives have no properties, and any attempt to retrieve a property (such as (0).constructor
) will cause Javascript to automatically convert it to an Object representation. E.g. (0)
becomes Number(0)
.(0)
is still a primitive, just with the addition of the grouping operators ()
. This is done here because, without the parentheses, the .
in 0.
is interpreted as a decimal point rather than a property accessor. You could achieve the same thing with 0..constructor
or a number of other ways.prototype
. You can see an object's prototype using its __proto__
property, e.g. (0).__proto__
. The prototype
is interesting because, when you try to access a property on the object, Javascript will also check the __proto__
object to see if that property exists on it. (This is used mainly for inheritance).__proto__
is constructor
. The constructor
is a function that is called when the object is first created.constructor
is of type Function
, which is itself an object with its own constructor
property.So, (0).constructor.constructor
is shorthand for Number(0).__proto__.constructor.__proto__.constructor
.
Your anonymous functions that return 9
do what they do because the constructor of a Function
accepts as an argument a string representation of some Javascript code. It's equivalent to doing this:
Function('return 9')()
;
Edit: corrected a mistake regarding autoboxing and (0)