When browsing minified Javascript code, I often see the following statement:
if (!''.replace(/^/, String)) {
// ...
}
What does this do? It seems that any ECMA-compliant JS interpreter will replace the beginning of the string with String('')
, which still results in an empty string, whose negation is true
.
In what circumstances will the behavior be different?
This seems to be coming from packers, like for exemple Dean Edwards javascript packer
So, let's download the code and see what it says ...
// code-snippet inserted into the unpacker to speed up decoding
const JSFUNCTION_decodeBody =
//_decode = function() {
// does the browser support String.replace where the
// replacement value is a function?
' if (!\'\'.replace(/^/, String)) {
// decode all the values we need
while ($count--) {
$decode[$encode($count)] = $keywords[$count] || $encode($count);
}
// global replacement function
$keywords = [function ($encoded) {return $decode[$encoded]}];
// generic match
$encode = function () {return \'\\\\w+\'};
// reset the loop counter - we are now doing a global replace
$count = 1;
}
';
It seems to check if the current browsers supports callbacks as the second argument to replace()
, and if yes takes advantage of that to speed things up.
As a remainder, String
in javascript is a function, the one you use when you do var foo = String('bar');
, although you probably rarely use that syntax if ever.
This can be used to check if the String
function wasn't overwritten by a careless developer.
In JavaScript nothing is immutable so:
!''.replace(/^/, String)
true //console prints
String
function String() { [native code] } //console prints
String()
"" //console prints
String = "eDSF"
"eDSF" //console prints
String()
TypeError: string is not a function //console prints
!''.replace(/^/, String)
false //console prints
Github shows 1053 examples with the same use.
// code-snippet inserted into the unpacker to speed up decoding
var _decode = function() {
// does the browser support String.replace where the
// replacement value is a function?
if (!''.replace(/^/, String)) {
// decode all the values we need
while ($count--) $decode[$encode($count)] = $keywords[$count] || $encode($count);
//...code code
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With