Search code examples
javascriptfunctionthisbind

Javascript: function binding does not work with caller


I have a function foo that calls function bar. foo is bound to an element test.

When being called, bar stores its caller function (foo) inside the set s. When I now run the function foo inside s, strangely this is now set to Window. But I did bind the function, so what am I getting wrong?

var s = new Set();

function bar() {
  s.add(bar.caller)
}

var test = document.getElementById('test');
test.foo = (function() {
  bar();
  console.log(this);
}).bind(test);

test.foo(); // output: test div
s.forEach(fn => fn()); // output: Window object
<div id="test"></div>


Solution

  • A bound function basically calls the function it is binding over¹ with the bounded this, so the callstack of your code looks like

     [Bound] test.foo -> test.foo -> bar
    

    So from bar's point of view, it was called from test.foo not from the bound function.²


    ¹ as stated in the spec:

    A bound function is an exotic object that wraps another function object. A bound function is callable (it has a [[Call]] internal method and may have a [[Construct]] internal method). Calling a bound function generally results in a call of its wrapped function


    ² wether function.caller returns the upmost callstack entry is not quite clear, as it is not specified. That's an assumption.