I know this
is probably the second most asked-about thing in javascript, right after floating point arithmetic.
I generally know how this
works, and how it's affected by arrow functions, .call()
, .apply()
, and .bind()
. I thought I understood everything about it. But I do not.
In a web browser, document.createElement("div").classList.add("c")
yields undefined
as expected. However, this expression surprisingly is an error.
(true && document.createElement("div").classList.add)("c")
I expected it to be the same, but it's
Uncaught TypeError: Illegal invocation
at <anonymous>:1:54
Your statement
(true && document.createElement("div").classList.add)("c")
can also be rewritten as following:
var add = (true && document.createElement("div").classList.add)
add("c")
[Logical AND (&&) expr1 && expr2 : Returns expr1 if it can be converted to false; otherwise, returns expr2.]
You see that function add
is now part of window
and loses reference of actual classList
object and hence cannot be called correctly.
add's this
now points to global object.
If you do following (if the new div is the only div on your page), it again has reference to the original object:
(true && document.createElement("div").classList.add).bind(document.getElementsByTagName("div")[0].classList)("c")
This will work, as it is returning this
as classlist
context
(document.createElement("div").classList.add)("c")
(true && document.createElement("div").classList.add)
will not work as add
is getting evaluated with && expression and after this its returning context of the expression (true && document.createElement("div").classList.add)
which is add() { [native code] }
and not classList and here we are trying to call add on add function.
When you are trying pass class name ("c")
to add
then this is not classlist
any more hence Illegal invocation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With