Reputation: 614
I am curious about something, imagine a link that closes the window. See the code below, and read the comments:
var a = document.querySelector('a');
//
// Since a.onclick requires a callback I have the following code:
//
a.onclick = function() { window.close() }; // This works fine.
a.onclick = function() { close() }; // This works as well.
a.onclick = () => { close() }; // This also work.
a.onclick = () => close(); // This works.
// But...
a.onclick = window.close; // This doesn't work.
a.onclick = close; // Neither this.
// But, why not?? Since onclick requires a function, and window.close is a
// function and close is just the shorten way to call window.close?
// However...
a.onclick = close.bind(); // This works fine....
So fellows, since onclick receives a function, why to set just "close" does not do the job? It should "register" the function close (window.close) as the "callback" for that action, and call it when the event was triggered (like close.call());
I really don't understand this behavior
Upvotes: 1
Views: 36
Reputation: 114014
This is a bit tricky.
We are so used to seeing window
holding all global variables that we have forgotten that window
itself is an object. That's right - it's the object that represent the browser window.
And close
is not merely a function but a method of the window
object (see: https://developer.mozilla.org/en-US/docs/Web/API/Window/close).
Thus when you convert close
to a function reference it loses it's binding to this
(which should point to window
).
The others work by happenstance:
a.onclick = function() { window.close() };
This is obvious. You're calling the method directly so it gets the correct this
.
a.onclick = function() { close() };
A function that does not belong to any object will have it's this either pointing to the global object (window
) or undefined
if in strict mode. So when not in strict mode this will work.
a.onclick = () => { close() };
Same explanation as number 2.
a.onclick = () => close();
Same explanation as 3 but not using the optional {}
.
Note: One may be tempted to think that 2, 3 and 4 are different mechanisms but while arrow functions affect how this
behave you're not calling this.close()
. Thus only the this
value in close
is important. The arrow functions don't change that.
Note that when not in strict mode the following should also work:
a.onclick = () => { this.close() }
I think it's fairly obvious from my previous explanations why the above should work.
Upvotes: 4
Reputation: 78920
It's all about the binding of the method to its this
. When you have a Function
reference to a method, then call it, it won't "know" which object the method belongs to (this
will no-longer be a Window
), so if .close()
needs to know about its window object, the function call will fail.
bind
works around this by fixing this
to a particular object:
a.onclick = window.close.bind(window);
Upvotes: 2