Approaching JavaScript with a classical object oriented mindset sets you up for failure and familiarity with class-based OO programming sets you up for confusion with 'this' in JavaScript.
Forget about what 'this' means in OOP languages and approach 'this' as an entirely new and independent concept. Remember JavaScript didn't get classes until ES2015 and even then those "classes" aren't "classical":
Objects aren't members of the creating class for life (they can be augmented at runtime) and neither do objects even need a class to be created. So while class is more than syntax sugar it's not about classical OOP.
The 'this' keyword evaluates to the value of the ThisBinding of the current execution context.
That's it. Nothing about objects and class didn't even exist yet. If you felt compelled to practice classical OO with JS you had to learn about prototype chaining, constructor stealing and combination, prototypal, parasitic and parasitic combination inheritance.
An execution context contains whatever state is necessary to track the execution progress of its associated code.
In practical terms this means that in general inside a function fn() the ThisBinding is determined by the way the function is called:
Call the function directly fn() then 'this' is the same as it would be for code at the top-level: undefined in a strict environment or globalThis in a non-strict environment.
When a function is invoked via the new operator 'this' refers to the object under construction.
Call the function via an object reference e.g. record['fn']() or record.fn() then the object will be bound to 'this'.
This mimics a method call but also enables reuse of a function bound to the prototype object for an object with that prototype object.
So just copying the function reference from an object property doesn't carry the ThisBinding with it.
Function.prototype.bind() creates an entirely new function which has its ThisBindingpermanently bound to the specified context.
ES2015 introduced arrow function expressions not as a shorthand for function () but as a bind -ing convenience as arrow functions will always bind their 'this' to the 'this' of the context that creates them.
If you know oops then
this
is no more confusing for you, but the way we use this inJS
is confusing.Approaching JavaScript with a classical object oriented mindset sets you up for failure and familiarity with class-based OO programming sets you up for confusion with 'this' in JavaScript.
Forget about what 'this' means in OOP languages and approach 'this' as an entirely new and independent concept. Remember JavaScript didn't get classes until ES2015 and even then those "classes" aren't "classical":
Quote
Objects aren't members of the creating
class
for life (they can be augmented at runtime) and neither do objects even need aclass
to be created. So whileclass
is more than syntax sugar it's not about classical OOP.Pre-
class
(ES5.1 and earlier)11.1 The 'this' Keyword
That's it. Nothing about objects and
class
didn't even exist yet. If you felt compelled to practice classical OO with JS you had to learn about prototype chaining, constructor stealing and combination, prototypal, parasitic and parasitic combination inheritance.Under 10.3 Execution Contexts
In practical terms this means that in general inside a
function fn()
the ThisBinding is determined by the way the function is called:fn()
then 'this' is the same as it would be for code at the top-level:undefined
in a strict environment orglobalThis
in a non-strict environment.record['fn']()
orrecord.fn()
then the object will be bound to 'this'.Function.prototype.bind() creates an entirely new function which has its ThisBinding permanently bound to the specified context.
ES2015 introduced arrow function expressions not as a shorthand for
function ()
but as abind
-ing convenience as arrow functions will always bind their 'this' to the 'this' of the context that creates them.Aside: JavaScript is Function-Oriented