Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does "if (!''.replace(/^/, String))" do?

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?

like image 547
tba Avatar asked Jun 28 '13 21:06

tba


2 Answers

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.

like image 127
Lepidosteus Avatar answered Oct 16 '22 23:10

Lepidosteus


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 
        }
    };
like image 27
raam86 Avatar answered Oct 16 '22 22:10

raam86