0

I understand that this inside an arrow function refers to a scope that's one level higher, and I remember like 2 months ago I was able to come up with an example of such case, but now, for the life of me, I cannot come up with a single example of this being used to refer to a function that is one level up, and not the global object.

document.getElementById("testthis").addEventListener("click", ()=> { 
     alert(this.innerWidth)
   })
<button id="testthis">TEST</button>

Here, this refers to the higher scope, which in this case is the global object - window.

Now If I want to put the event listener inside another function, is that function going to become the 'one level up' scope? If so, is this now referring to it? If so, then what exactly does it refer to? Can you give me an example of this refer to something inside the parent function?

   function outer() { 
   
   document.getElementById("testthis").addEventListener("click", ()=> { 
         alert(this.innerWidth)
       })
       
  }
  
   outer();
<button id="testthis">TEST</button>

I've used this to refer again to innerWidth, which is a property of the global object, and it works, so therefore, this again refers to the global object, and not to the parent function. Why?

I'm so confused. Can somebody please make this clear for me.

Note: Yes, I've done plenty of research, but nobody talked about this particular question.

definitelynotme
  • 103
  • 1
  • 6
  • 1
    `outer();` -> `outer.call({this: "is my custom 'this' variable"});` – VLAZ Mar 22 '21 at 12:52
  • 2
    `this` is determined by the (parent) `function` execution context, so it gets its value when that `function` is called (possibly bound). – trincot Mar 22 '21 at 12:55
  • It's not the next parent function, but the next one that has a context (and is it's parent). In my case it usually is either an eventlistener, or the class. The context kind of refers to "settings" of a class in this case. Maybe this helps: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this – Frizzant Mar 22 '21 at 13:11
  • @VLAZ I don't understand what this means. Can you elaborate? Are you defining `this` as a property? of which object? – definitelynotme Mar 22 '21 at 13:16
  • Also, why was my question closed? I have read the suggested question, and it does not answer my question. Nowhere in the suggested question is it being explained what I am asking for. – definitelynotme Mar 22 '21 at 13:17
  • @trincot Yes, I know that, and my question was to WHAT does `this` refer to in the higher up function? To What? Give me an example. That's all I want. – definitelynotme Mar 22 '21 at 13:18
  • 1
    "*Nowhere in the suggested question is it being explained what I am asking for.*" [yes, it is](https://i.imgur.com/m5llwiW.png). Moreover, the entire Q&A is how `this` works. It's required knowledge. – VLAZ Mar 22 '21 at 13:18
  • @Frizzant Can you PLEASE give me an example? The link you're giving me does not explain the case I am referring to. Literally all these explanations only refer to an object where `this` is used inside a method. That's far from the case I am asking about. – definitelynotme Mar 22 '21 at 13:20
  • @VLAZ Again, I have read these, and this is NOT my question. Please read my question a second time. Your giving me an example of `this` used inside a method. Obviously I know it refers to the object owner. This is NOT what I am asking for. I am asking for arrow function inside another function. NOT object. I am asking, what does `this` refers to INSIDE the higher function. Please try to understand my question. – definitelynotme Mar 22 '21 at 13:23
  • 2
    @definitelynotme did you read and understand the duplicate then? Because it goes into excruciating detail of what the value of `this` would be. – VLAZ Mar 22 '21 at 13:24
  • Yes, I've read multiple similar explanations. They are not actually addressing my situation. They are all referring to literally one case only, in which a new object is created, and a method is created, and `this` is used inside the method. I am not interested in this case. My case is completely different. Look at my snippet. I am not using an object. I am creating event listener inside a function, and asking if `this` inside the arrow function that is inside the event listener refers to the parent function, and if yes, TO WHAT does it refer inside of it, and why does it refer to `window`. – definitelynotme Mar 22 '21 at 13:27
  • @definitelynotme it refers to the `window` object *because you've executed `outer()` in the global context in sloppy mode.* https://i.imgur.com/g7Jh3oe.png and https://i.imgur.com/WHL9qGA.png – VLAZ Mar 22 '21 at 13:28
  • @VLAZ Okay, so in what context can `this` inside an arrow function refer to a parent function? I could've sworn that like last month I came up with several such examples, and now It's as if they were deleted from my memory. Also, I don't want to use `return this` I want `this` to refer to SOMETHING inside the parent function. This is what I want. – definitelynotme Mar 22 '21 at 13:41
  • @definitelynotme `this` almost never refers *to the function*. It could but again - it depends on how it's executed. Invoking the function through `.call()` or `.apply()` allow for directly substituting the value of `this` at execution time. `.bind()` works similar but the new function it returns has a permanently set value of `this`. Calling a *method* implicitly sets `this` to the object it was from. There is no implicit way for a function to refer to itself, unless you do something like `fn = function(){}; fn.fn = fn;. fn.fn()`. The other alternative is `fn.call(fn)` – VLAZ Mar 22 '21 at 13:46
  • 1
    First: the arrow function does not have an impact on `this`, whether you consult `this` inside its body, or just before/after its definition, it is the same `this`. The value of `this` is determined by how the parent `function` was called. If you call it with property notation (like `obj.myFunc()`) then `this` is `obj`. If you call it "standalone" (like `myFunc()`) then `this` will be the global object (or `undefined` in strict mode). If you call it with `call` or `apply`, then you pass the value for `this`. If you have defined a function with `bind`, you forever determine `this` for each call – trincot Mar 22 '21 at 13:57
  • 1
    All this is explained the duplicate reference, BTW. – trincot Mar 22 '21 at 13:58
  • @VLAZ Substitute the value of `this`.. with WHAT? This is the crux of my question. What does `this` refer to INSIDE the parent function? – definitelynotme Mar 22 '21 at 14:37
  • 1
    @definitelynotme [it refers to the `window` object](https://i.imgur.com/G7Dga0U.png) – VLAZ Mar 22 '21 at 14:42
  • @trincot So there is no case in which, like my snippet, an arrow function attached to an event listener contains `this`, and the event listener is inside a parent function, and `this` refers to something inside the parent function? Then what does it mean that `this` inside an arrow function refers to one level up the scope? I could've sworn that I created an example where I nested an arrow function inside another function, and `this` inside the arrow function referred to something inside the parent function. I am desperate to remember what case was that.. – definitelynotme Mar 22 '21 at 14:48
  • @VLAZ I am not talking about the global object. By "parent function", I mean a function nested inside another function. – definitelynotme Mar 22 '21 at 14:49
  • 1
    @definitelynotme you asked what the value of `this` is in the parent function. That function is `outer()`. In this case it's the global `window`. Because you've called it in the global scope. And you're in sloppy mode. The arrow function will have the same `this` as in `outer`. – VLAZ Mar 22 '21 at 14:51
  • 1
    `this` can refer to anything, but it is essentially determined by the caller of `function`, not by the function. So in *different* calls of the same function, you can have *different* values of `this`. By looking at a `function` you cannot know what `this` is... You need to see its *call*. Whether or not there is an arrow-function defined within your `function`, doesn't really matter: the code *inside* that arrow function will see the same `this` as the `function`'s code that is not... The arrow function is irrelevant here. – trincot Mar 22 '21 at 14:51
  • 1
    You should regard `this` as a special argument of a `function`. You cannot know `this` until a `function` is called - just like you don't know what the actual value of normal function parameters will be, until the `function` is called. Both the value for `this` and the parameters are determined at the *call* of a `function`. Arrow functions don't have this extra parameter behaviour, and so any reference to `this` in arrow functions is the same as what the rest of the parent `function` sees as `this`. – trincot Mar 22 '21 at 15:00
  • @trincot So you're saying that, in my second snippet, `this` inside the arrow function refers to the parent `outer` function in the same way as if `this` is used inside the `outer` function, which would mean that `this` refers to whoever is calling the function? If it's triggered in the global scope, it refers to the global object, if it's triggered by an event, it refers to the element that triggered it, and so on? – definitelynotme Mar 22 '21 at 15:32
  • "_So you're saying that, in my second snippet, `this` inside the arrow function refers to the parent `outer` function in the same way as if `this` is used inside the outer function_" Yes. "_which would mean that `this` refers to whoever is calling the function?_" No. For regular (non-arrow) functions, it depends on _how_ the function is called. Not from _where_. Arrow functions on the other hand inherit the `this` from the [lexical scope](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#lexical_scoping). (All of this, again, is explained in the duplicate.) – Ivar Mar 22 '21 at 15:46
  • 1
    `this` does not refer to a function, nor does it refer to "whomever is calling" -- that is an odd way of putting it. `this` is initialised *by* the caller of that `function` to whatever the caller wants (or a default will be used). So in your second snippet we see a "standalone" type of call of `outer()`: that is where you say that `this` is going to refer the global object. Whether you have an arrow function embedded or not, is irrelevant. Whether that arrow function is triggered by an event, is irrelevant. – trincot Mar 22 '21 at 15:46
  • @Ivar `inherit "this" from the lexical scope` .. what do they inherit? Doesn't `this` inside the parent function refer to the global object? therefore.. `this` inside an arrow function which is inside a parent function would refer to the parent function, which then determines what `this` refers to depending on how it's triggered. Is that not correct? – definitelynotme Mar 22 '21 at 16:11
  • @trincot I really appreciate you trying to help me, but could you please try to be a bit more specific with the words you're using? It's the details that are confusing me, and the words you're using are ambiguous. I think if you were to give me a very simple example, that would help me understand it better. "`this` is initiated by the caller of that function" ... so in my second snippet, that would be the `testthis` element, correct? ".. to whatever the caller wants" .. what is that mean exactly? TO whoever the caller wants? What default? Is the essence of my above understanding correct? – definitelynotme Mar 22 '21 at 16:24
  • No. (1) The element does not call. It is the DOM API that makes the call, and (2) that call is irrelevant, because that call is made to an arrow function, which **does not influence `this`**. Calls to *arrow* functions ***never*** influence `this`. The only time you have determined a value for `this` in your second code block has nothing to do with `testthis`, nor with an event, nor with the arrow function. It is how the main script made a call to `outer`. That is the only time that `this` was determined. It didn't change by the event, nor the handler for it. – trincot Mar 22 '21 at 16:29
  • In my other comment "initiated" was a typo. I meant "initialised". – trincot Mar 22 '21 at 16:30
  • When I say "whatever the caller wants", I mean just like determining the value of a function argument. For instance, I have a `function say(msg) {...}`. Then I can choose to call `say("hello")` or `say("bye")`. I determined the value of the parameter that `say` expects. Similarly, I can determine the value of `this` by doing `say.call({}, "hello")` or `say.call(Math, "hello")`. Now `this` will be either `{}` or `Math`. If I just do `say("hello")`, then `this` is the global object. This applies to `outer` in your example, but not to the event handler, because the latter is an *arrow function*. – trincot Mar 22 '21 at 16:37
  • @VLAZ Could you please read my comment that starts with `So you're saying that..` and tell me is my understanding correct or wrong? Even if it's not exactly technically correct, is it in essence correct? – definitelynotme Mar 22 '21 at 17:00
  • @definitelynotme more or less. As has been said, arrow functions don't have their own `this`, they just inherit the one from the place they are defined in. Since `outer` is executed with `this` set to `window`, the arrow function has a `this` equal to `window`. Again, though the *way the function is called* determines the value of `this`. It's not "who" calls it, it's "how". – VLAZ Mar 22 '21 at 17:04
  • "what do they inherit?" the value of `this`. Also, `arguments` but we can ignore that. "*Doesn't this inside the parent function refer to the global object?*" yes, which is what the arrow function inherits. It *literally* doesn't have its own `this` - when `outer` is called, it gets a value for `this` and the arrow function *uses the same binding*. There isn't a new `this` created for it. https://jsbin.com/karexobeko/1/edit?js,console – VLAZ Mar 22 '21 at 17:16
  • @VLAZ Yes, I think my understand was correct then. Isn't that what I said as well? Which part of my understanding was incorrect? – definitelynotme Mar 22 '21 at 18:56

0 Answers0