"some expression" runs during the construction of the object so this refers to the object under construction as it is typical for constructor functions.
classWhatever{someMethod=(()=>{// IIFE body})();}
in this case the expression is an Immediately Invoked Function Expression (IIFE) - i.e. after the function expression creates the function, the function is immediately executed. All of this still happens inside the constructor function and the return value of that IIFE is assigned to the someMethod property of the object under construction.
Inside the IIFE this is copied to outerThis and the IIFE is the closure that creates the function that is assigned to someMethod. But given that all of this is still happening inside the constructor function this is still simply the object under construction.
This may make it more clear what is actually happening:
// Constructor FunctionfunctionWhatever(){// When invoked by `new`, i.e. `new Whatever()`// `new` passes the object under construction// as `this` to `Whatever`constmakeFunction=()=>{constouterThis=this;constbuiltFunction=()=>{return[outerThis,this];};returnbuiltFunction;};this.someMethod=makeFunction();// Note the lack of the a return statement/value// It's `new` that returns the constructed object// not `Whatever`.}constwhatever=newWhatever();const[outer,inner]=whatever.someMethod();console.assert(outer===inner);console.assert(outer===whatever);console.assert(inner===whatever);
functionjustSomeFunction(){constmakeFunction=()=>{constouterThis=this;constbuiltFunction=()=>{return[outerThis,this];};returnbuiltFunction;};this.someMethod=makeFunction();}// passing an object literal as `this` with `call`constobj={};justSomeFunction.call(obj);const[outer,inner]=obj.someMethod();console.assert(outer===inner);console.assert(outer===obj);console.assert(inner===obj);
This is why inside functions this is called the function context. It's the context that is passed to the function so it can do its job. If the function operates as a method the function context refers to the object to which it was invoked on. But in a constructor function the function context refers to the object under construction. So what this is depends entirely on how a function is invoked. Arrow function expressions change the rules - this refers to whatever this was in the creating closure when the arrow function was created. This means that arrow functions on super-types won't work for sub-types because sub-types are unable to pass in their own this into the arrow function.
classA{myArrow=()=>{console.log('A.myArrow()');}myMethod(){console.log('A.myMethod()');}}classBextendsA{myArrow=()=>{super.myArrow();// arrow function exists on // public class field of A but// but is not available on // the prototype chain via `super`console.log('B.myArrow()');}myMix(){super.myArrow();// same problemconsole.log('B.myMix()');}myMethod(){super.myMethod();// just worksconsole.log('B.myMethod()');}}letmyB=newB();myB.myMethod();// 'A.myMethod()'// 'B.myMethod()'myB.myMix();// Uncaught TypeError: (intermediate value).myArrow is not a function at B.myMixmyB.myArrow();// Uncaught TypeError: (intermediate value).myArrow is not a function at B.myArrow
Thanks for clarification, I had assumed that IIFE captured this as class is created in scope of globalThis, but now I understand that fields of class are invoked inside constructor.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Well I was wrong, I learned that
this
is even available as arrow function that is created inside the class.To understand
this
in arrow functions you need to understand closures/scope.Because
this
inside an arrow function refers to whateverthis
was in the closure at the point in time the arrow function was created.Dissecting ...
this
refers to the object under construction as it is typical for constructor functions.someMethod
property of the object under construction.this
is copied toouterThis
and the IIFE is the closure that creates the function that is assigned tosomeMethod
. But given that all of this is still happening inside the constructor functionthis
is still simply the object under construction.This may make it more clear what is actually happening:
Similarly with Function.prototype.call():
This is why inside functions
this
is called the function context. It's the context that is passed to the function so it can do its job. If the function operates as a method the function context refers to the object to which it was invoked on. But in a constructor function the function context refers to the object under construction. So whatthis
is depends entirely on how a function is invoked. Arrow function expressions change the rules -this
refers to whateverthis
was in the creating closure when the arrow function was created. This means that arrow functions on super-types won't work for sub-types because sub-types are unable to pass in their ownthis
into the arrow function.For an interesting application of closures see OOP with Functions in JavaScript.
Thanks for clarification, I had assumed that IIFE captured
this
asclass
is created in scope ofglobalThis
, but now I understand that fields of class are invoked inside constructor.