Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
11 Ways to Invoke a Function
console.log(1);
(_ => console.log(2))();
eval('console.log(3);');
console.log.call(null, 4);
console.log.apply(null, [5]);
new Function('console.log(6)')();
Reflect.apply(console.log, null, [7])
Reflect.construct(function(){console.log(8)}, []);
Function.prototype.apply.call(console.log, null, [9]);
Function.prototype.call.call(console.log, null, 10);
new (require('vm').Script)('console.log(11)').runInThisContext();

Delagen commented Apr 7, 2017 edited

I think the correct way to invoke functions similar will be

console.log.call(console, 4);
console.log.apply(console, [5]);
Reflect.apply(console.log, console, [7])
Function.prototype.apply.call(console.log, console, [9]);
Function.prototype.call.call(console.log, console, 10);

console.log is generic function and does not use this context, so this works with null

mrtbld commented Apr 7, 2017 edited

console.log is generic function and does not use this context

That's not exact, it does use this [0], it's just that it's pre-bound to the Console instance [1]. (At least in node.js.)

But your right, those examples wouldn't work for methods that aren't bound to their instance, which is what happens by default.

[0] https://github.com/nodejs/node/blob/a94a5da78c6fdecf1aef541db237a1c96a9801a3/lib/console.js#L103-L108
[1] https://github.com/nodejs/node/blob/a94a5da78c6fdecf1aef541db237a1c96a9801a3/lib/console.js#L57-L62

A 12th:

({
  get accessorFunc() {
    console.log(12);
  }
}).accessorFunc; // this invokes the function

Kovensky commented Apr 7, 2017 edited

;((_ = console.log(13)) => {})()
;(class extends (console.log(14), null) {}) // cheating maybe?
// this can always go deeper
Function.prototype.apply.apply(Function.prototype.apply, [Function.prototype.apply, [console.log, [console, [15]]]])

blindman67 commented Apr 7, 2017 edited

do these count?

;(console.log)(16)
{let a;( a="log",console[a])(17)}
{let t,b;(t=this,b=(a)=>t=t[a],["console","log"].forEach(b),t(18))}
{let t,b,c="console.log";(t=this,b=(a)=>t=t[a],c.split(".").forEach(b),t(19))}
((...a)=>this[a[0]][a[1]](20))("console","log")

bahmutov commented Apr 7, 2017

I will just leave this here

function foo() {}
foo``

Vanuan commented Apr 7, 2017

There are only 3 ways:

var message = 'message';
console.log(message); // 1
console.log.call(console, message); // 2
console.log.apply(console, [message]); // 3, array-like 'call'

Other "ways" are just ways to access either call/apply methods or a function to be called.

(_ => console.log(2))(); // Way 1 + IIFE (which is also way 1)
eval('console.log(3);'); // Way 1 + eval
new Function('console.log(6)')(); // Way 1 + new Function
Reflect.apply(console.log, null, [7]) // Way 3 + Reflect alias for Function.prototype
Reflect.construct(function(){console.log(8)}, []); // Way 1 + Reflect alias for new Function
Function.prototype.apply.call(console.log, null, [9]); // Way 3 using prototype form
Function.prototype.call.call(console.log, null, 10); // Way 2 using prototype from
new (require('vm').Script)('console.log(11)').runInThisContext(); // Way 1 + obscure way to use eval
// browser, sync
setTimeout('console.log(12)');

// node and browser, sync
new function () { console.log(13) };
(s => console.log(s[0]))`14`

// node and browser, async
setTimeout(console.log, 0, 15);

getify commented Apr 7, 2017 edited

console.log.bind(console)(12)

Haha, I don't think this is a compliment to the language ... ;)

lirantal commented Apr 7, 2017

And... the weirdest of all:

!function () { console.log(42) }()
Function.prototype.call.call(console.log, null, 12);
Function.prototype.call.call.call(console.log, null, 13);
Function.prototype.call.call.call.call(console.log, null, 14);
Function.prototype.call.call.call.call.call(console.log, null, 15);
Function.prototype.call.call.call.call.call.call(console.log, null, 16);
Function.prototype.call.call.call.call.call.call.call(console.log, null, 17);

;)

Tagged template literals ftw!

i3games commented Apr 8, 2017 edited

[]["map"]["constructor"]("console.log(18)")()

The weirdest is far this one mentioned above:

function foo() {}
foo``

Styled components shocked the world with this syntax

pwang2 commented Apr 8, 2017

var foo=function(d){console.log(d)}
foo`dd`
VM219:1 ["dd", raw: Array[1]]

any explanation?

davidmarkclements commented Apr 8, 2017 edited

@pwang2 https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals

another form of IIFE (makes function into expression) but I think it's semantically nicer:

void function () { console.log('19') }()

Also in terms of "hidden" or unexpected execution:

var o = {toString: () => console.log('20')}
var n= +o //20
~o //20
o + ''  //20
var s = `${o}` //20
o[o] //20
parseFloat(o, 10) //20
o++ //20
var o = {valueOf: () => console.log('21')}
var n= +o //21
~o //21
o + ''  //21
var s = `${o}` //21
o[o] //21
parseFloat(o, 10) //21
o++ //21
var o = {[Symbol.toPrimitive]: () => console.log('22')}
var n= +o // 22
~o //22
o + '' //22
var s = `${o}` //22
o[o] //22
parseFloat(o, 10) //22
o++ //22

node only:

var o = {inspect: () => console.log('23')}
console.log(o) // 23

You can also make functions calls for any object (that isn't pure - e.g. inheriting from null)

Object.prototype.toString = () => { console.log('24') }
Object.prototype.valueOf = () => { console.log('25') }
parseFloat({}, 10) //24
''[{}] // 24
1 + {} // 25
1 + function () {} // 25
Object.prototype[Symbol.toPrimitive] = () => { console.log('26') }
parseFloat({}, 10) //26
''[{}] // 26
1 + {} // 26
1 + function () {} // 26

And then there's meta programming for side effect calls:

var p = new Proxy({}, {
  has: (t, k) => {
    console.log('27')
    return true
  }
})


if ('foo' in p) {}  // 27
with (p) {
  moo + shoe //27 27
}

Object.prototype.hasOwnProperty = new Proxy(Object.prototype.hasOwnProperty, {
  apply: (t, self, args) => {
    console.log('28')
    return t.apply(self, args)
  }
})

var o = {}

if (o.hasOwnProperty('a')) {} // 28

As one liner "function calls":

+{[Symbol.toPrimitive]: () => console.log('x')}
+{toString: console.log.bind(console, 'x')}
+{valueOf: console.log.bind(console, 'x')}
'x' in (new Proxy({}, {has: () => console.log('x')}))
with (new Proxy({}, {has: () => (console.log('x'),1)})) callThatThing

More:

({get x() { console.log('x') }}).x
Object.create(null, {x: {get: () => console.log('x')}}).x

v8 only (node, chrome):

Error.prepareStackTrace = () => console.log('x'); Error()
Error.prepareStackTrace = () => console.log('x'); try { u } catch(e) { e }

SpencerJobe commented Apr 9, 2017 edited

Does this count?

var i = document.createElement("img");
i.onerror = function() { console.log(1); };
i.src = "nope";

do not forget constructor without parenthesis so mainly 5 way.
function A () {};
new A;
A``;
A();
A.call();
A.apply();

with double colon bind operator:
console::(console.log)(0)

jorrit commented Apr 11, 2017

Promise.resolve(19).then(console.log)

guillermo commented Jun 18, 2017 edited

console["log"](9)

Using Proxy (not yet mentioned) you can make accessing, setting, etc a property to be an actual function call:

const log = new Proxy(console.log, {
  get: (orig, key) => orig(key)
});

log[11];

Based on this awesome/awful feature I created a little monster:

const buttons = dom.button.html;
dom.a.html = 'Hello world';

dosyago-coder-0 commented Jun 19, 2017 edited

I'm a fan of this one:

(class { [console.log(1)](){} })
({[console.log(1)](){}})
(function z( a = console.log(1) ){})()
[...{[Symbol.iterator](){return {next(){ return {done:console.log(1)}}}}}]; // hehe
try{[1,2,3][~~(Math.random()*4)].toString()}catch(e){console.log(12)}; // nondeterministically run console.log 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment