Weird thing about Self-executing functions

Viewed 60

I stumbled upon something in a validation library where they use a required-validation as part of a validation function.

Now, the weirdness that I cant seem to find or read myself to sanity about has to do with self-executing functions. This is from the code.

value => !(0,req)(value) || [...some more checks]

Now.. the req() method takes one argument, so far we're good. What got me interested was that we could write req(value) or (req)(value) just as well.. but that little zero in front seems like totally useless.

I tried a lot of stuff here, using alert() and came to one weird conclusion. I ran these cases inspector console for testing the output. works just as fine as which works just as fine as the following:

(alert)('hello') » gives a 'hello' alert

(0,alert)('hello') » gives a 'hello' alert

(0,1,3,5,1,alert)('hello') » gives a 'hello' alert

(console.log,alert)('hello') » gives a 'hello' alert

(alert,1)('hello') » gives an error (alert,1) is not a function

(alert,console.log)('hello') » gives a console log 'hello

(alert,1,"test",console.log)('hello') » gives a console log 'hello


Can anybody explain to me how this resolution works?

Why does it seem to go with the latest method provided and therefore (0,alert) do the same as (alert) and as (0, console.log, "test", alert)?

2 Answers

It because It take last value from the brackets and execute the code:

    a = [1, 2, 3]
    b = [4, 5, 6]
    console.log((a,b)[0]) //prints 4
    //because Its JavaScript's default behaviour
    x = function(){alert("foo")};
    y = function(){alert("bar")};
    (x,y)() // alerts bar
    //because it takes last function which is y
    //also  for simple variable
    p = 10;
    q = 20;
    console.log((p,q)); //prints 20

There isn't anything specific about methods/functions here. You're just seeing the Comma operator in action.

The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.

For example, (alert,1,"test",console.log) evaluates to console.log, and then the ('hello') afterward is just doing a call on that function.

It's confusing because the parentheses in this code are used for two separate things: surrounding an expression or calling a function. It only means "calling a function" if it follows a function. Otherwise, the comma operator is what will kick in.

(note that minifiers are able to use the comma operator to shrink down code, but please don't use in real code since it's super esoteric).

Related