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?
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?
Share Improve this question asked Jun 28, 2013 at 21:17 tbatba 6,5718 gold badges45 silver badges63 bronze badges 4 |2 Answers
Reset to default 18This 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
Of course this isn't what most people use it for.
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
}
};
(!''.replace(/^/, String))
with SymbolHound – Rory O'Kane Commented Jun 28, 2013 at 21:25alert("example");
and look at the output. – Rory O'Kane Commented Jun 28, 2013 at 21:30