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
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
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

@ashsearle

A 12th:

({
  get accessorFunc() {
    console.log(12);
  }
}).accessorFunc; // this invokes the function
@Kovensky
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
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
bahmutov commented Apr 7, 2017

I will just leave this here

function foo() {}
foo``
@Vanuan
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
@WebReflection
// 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
getify commented Apr 7, 2017 edited

console.log.bind(console)(12)

@polterguy

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

@lirantal
lirantal commented Apr 7, 2017

And... the weirdest of all:

!function () { console.log(42) }()
@salomvary
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);

;)

@wesleysmyth

Tagged template literals ftw!

@i3games
i3games commented Apr 8, 2017 edited

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

@leonardoanalista

The weirdest is far this one mentioned above:

function foo() {}
foo``

Styled components shocked the world with this syntax

@pwang2
pwang2 commented Apr 8, 2017
var foo=function(d){console.log(d)}
foo`dd`
VM219:1 ["dd", raw: Array[1]]

any explanation?

@davidmarkclements
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
@davidmarkclements

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
SpencerJobe commented Apr 9, 2017 edited

Does this count?

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

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

@gonzaloruizdevilla

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

@jorrit
jorrit commented Apr 11, 2017
Promise.resolve(19).then(console.log)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment