4 ms·
Ways to Invoke a Function in JavaScript
- fred256 9y agoNumber 2 is cheating IMHO: it is invoking console.log just like 1, just wrapped in an immediately invoked closure. You can keep playing this game ad infinitum: (_ => (_ => console.log("2a"))()() (_ => (_ => (_ => console.log("2b"))))()()()
- kmill 9y agoI wasn't reading carefully, and I thought they mentioned it because it's slightly different from (function () { console.log("#"); })(); though not actually since the this is not being used. I was expecting to see console.log.bind(console)("#") as well. Edit: bind is farther down in the comments.
- jmull 9y agobind is a way to create a function, not invoke one. Here you're invoking the function (that bind returned) in the normal way, using parenthesis.
- kmill 9y agoThe list seems to be about different ways a particular function could be called, rather than just the syntax of invocation. Imagine you are making a code analysis program and you want to find all the places console.log is called; I imagined the bind example as encompassing things like var log = console.log.bind(console); // ... ... ... log("#");
- jmull 9y agoOk: static analysis of a language where most fundamental relationships are resolved at runtime. I guess this is one way to express the futility. The lesson learned is hook console.log -- or whatever function you are interested in -- meaning, replace it with something that captures the context in which it is called and passes through the call to the original)
- Stratoscope 9y agoExactly. And if anything is notable about #2, then these must be notable too: ( function() { console.log("2f") } )() ~function() { console.log("2f") }()
- amelius 9y agoAt least this one is cheating: (_ => console.log(2))(); This is creating a function from which the function (console.log) is invoked. So not a direct call, but two calls instead.
- owebmaster 9y agoNot cheating, this is an anon function and its call
- shawnz 9y agobut the inner function is not anonymous, which is the focus of the question.
- underwater 9y ago`log` is invoked by the expression `console.log(2)`. That's exactly the same as example 1.
- jmull 9y agoA bunch of these are cheating... just wrapping () in various ways or accessing call and apply in various ways. For general functions, I think the commenter who says there are three ways to invoke a function is correct: (), call, apply. There are additional ways specific functions are called -- I'm thinking of toString and valueOf.
- underwater 9y agoYeah, considering that `Function.prototype.apply === console.log.apply` there are a lot of dupes here. I would consider eval/new Function to be a legitimate fourth way though.
- jmull 9y agoYes, you have a good point about eval and anything else that boils down to invoking a string as a function.
- vmarquet 9y agoAnd the weirdest way of all to do a console.log(1): [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]](([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+![]+[![]]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])() How: http://www.jsfuck.com/ http://www.jsfuck.com/ As a side note, jsfuck is usefull for bypassing filters who try to prevent the exploitation of XSS vulnerabilities.
- deleted 9y ago[deleted]
- abalashov 9y agoAnd I assume that the fact of this multiplicity is not seen to be the manifestation of a problem with the language? :-)
- AgentME 9y agoIf one is trying to find redundancy in the language, one might want to ignore the redundant items in the list first: * 2 and 8 are literally just 1 inside of a callback, which is weird to be this list. Might as well also have `var x = console.log(1);` while we're at it. * 11 is some Nodejs specific way of making a new context and then running code on it. It's somewhat equivalent to doing this in bash: `echo "#!/bin/bash\necho 123" > script.sh && bash script.sh`. I think it's pushing it to call that a way to run a function within the language. A few are natural consequences of how the `this` parameter and classes work in Javascript. (Not to say that the way the `this` parameter and classes work in Javascript is above criticism, but they do make certain kinds of behavior easy that would require relatively painful reflection in Java to do, so if anything one should compare them to Java's reflection APIs.) * 4 shows the call method of functions, which lets you provide a different `this` parameter to a function call than the automatically inferred one. (In a regular call to `console.log(1)`, the log function from the console object is called with console as the `this` parameter and 1 as the first normal parameter.) * 9 and 10 are just demonstrations of that all methods can be retrieved from the object that owns them or the class they came from. Some of the kinda redundant-looking ones have uses which I think pays for their existence: * 6 is using an eval-like shortcut to parse a string into a callable function rather than executing it immediately, and unlike eval, it doesn't get access to variables within the current scope, which makes the code easier to analyze. Anywhere `eval` is used with a dynamic string, you've got to wonder about how it could screw with variables within the current scope. * 5 is the way to supply a function with a variable number of arguments supplied by an array. ES6 has added some nice syntax sugar for this at least: `console.log(...someArray)`. * 7 shows the `Reflect.apply` function, which is equivalent to `Function.prototype.apply.call`. The global `Reflect` object is provided as a convenience/demonstration as a default no-op pass-through implementation of a Proxy handler. There's almost no need to ever use the Reflect object outside of setting up a Proxy object. Calling it redundant would be like drawing an equivalence between tissues and toilet paper and wondering why anyone bothers buying toilet paper separately: it's because it's put into a convenient form-factor for a specific use.
- franciscop 9y agoMake accessing or setting a property to be an actual function call with Proxy: const log = new Proxy(console.log, { get: (orig, key) => orig(key) }); log[11];
- 19eightyfour 9y agoWhich one of these would be cheating? [...{[Symbol.iterator](){return {next(){ return {done:console.log(1)}}}}}]; JSON.parse("[]",()=>console.log(1))
- sillysaurus3 9y agoThat first example is pretty amusing.
- 19eightyfour 9y agoYeah i got a chuckle out of it when i crashed my console session.
- yladiz 9y agoFunny enough, if you take the first and put it into babeljs.io, it will cause it to crash the tab.
- 19eightyfour 9y ago"Owned." Heh.