Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is "this" in javascript when calling a method on a calculated object?

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
like image 624
recursive Avatar asked Mar 31 '17 06:03

recursive


2 Answers

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")
like image 195
pranavjindal999 Avatar answered Nov 14 '22 03:11

pranavjindal999


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

like image 31
Anil Avatar answered Nov 14 '22 02:11

Anil