The five rules of this — priority order
flowchart TD
A["<b>i · Call site</b><br/>how is the function invoked?"]
--> N{"<b>ii · new Foo()?</b>"}
N -- yes --> NO["<b>this</b> = fresh object<br/>(constructor binding)"]
N -- no --> E{"<b>iii · call / apply / bind?</b>"}
E -- yes --> EO["<b>this</b> = the explicit context"]
E -- no --> I{"<b>iv · obj.fn() ?</b>"}
I -- yes --> IO["<b>this</b> = obj<br/>(implicit binding)"]
I -- no --> D{"<b>v · arrow function?</b>"}
D -- yes --> DO["<b>this</b> = enclosing lexical this<br/>(cannot override)"]
D -- no --> DB["<b>vi · default binding</b><br/>window (non-strict) / undefined (strict)"]
classDef head fill:#f5efe1,stroke:#6a8a4f,stroke-width:2px,color:#1a1915;
classDef branch fill:#fdecd3,stroke:#c2410c,stroke-width:2px,color:#1a1915;
classDef leaf fill:#e7efd9,stroke:#587640,stroke-width:2px,color:#1a1915;
class A head
class N,E,I,D branch
class NO,EO,IO,DO,DB leaf-
Call site
The exact way the function is invoked decides this — not where the function was declared.
-
new Foo()
Highest priority. Constructor binds this to a brand-new empty object.
-
call / apply / bind
Explicit binding: you pass the context directly. bind returns a new function with this locked.
-
obj.fn()
Implicit binding: this = the object before the dot. Lose the dot → lose the binding.
-
Arrow function
No own this. Inherits from the enclosing lexical scope. call/apply/bind cannot change it.
-
Default binding
Fallback when none of the above match. window in non-strict mode, undefined in strict mode.
Comments
Comments are disabled in this environment. Set
PUBLIC_GISCUS_REPO,PUBLIC_GISCUS_REPO_ID, andPUBLIC_GISCUS_CATEGORY_IDto enable.