Javascript context i.e the 'this' keyword is quite a confusing topic in itself. Although, being very simple and semantic, it has been easy for me to forget the rules around context. With further ado, Let me introduce the cheatsheet for the infamous 'this' keyword!
Quick side note: This article is intended as a cheatsheet around JS context, It does not serve as a verbose explanation of the concept. If you are beginner and have not explored the 'context' concept yet, I highly recommend you to read this
MDN doc first
Cheatsheet:
Use case | this | Example | Normal Functions |
---|---|---|
Invoked directly | window |
fn() // this -> window |
Invoked from object [Implicit Binding] |
Invoking object |
obj.fn() // this -> obj |
Explicit Binding (bind, call, apply) |
Passed reference |
// --- .call .apply --- // obj.fn.call(otherObj) // this -> otherObj |
Invoked in
strict mode |
undefined [[ If this->window ]] |
'use strict' fn() // this -> undefined window.globalFn = fn window.globalFn() // this -> undefined obj.fn.call(window) // this -> undefined |
Arrow Functions |
Instantiation context: The value of 'this'[Context] when an object instance is created using a constructor. |
||
Invoked [directly OR from object] |
Instantiation context |
// ----- direct invocation ---- // // Instantiation context: window const fn = () => console.log(this) fn() // this -> window // ----- invocation from obj [class instance] ---- // function myClass(){ this.fn = () => console.log(this) } -- OR -- class myClass { constructor(){ this.fn = () => console.log(this) } } // Instantiation context: obj1 const obj1 = new myClass() obj1.fn() // this -> obj1 // ----- invocation from obj ---- // // Instantiation context: window const obj2 = { fn: () => console.log(this) } obj2.fn() // this -> window |
Explicit Binding (bind, call, apply) |
Instantiation context [No Effect] |
obj.fn.call(otherObj) // this -> window instance.fn.call(otherObj) // this -> instance |
Invoked in strict mode |
undefined [[ if this -> window ]] |
'use strict' fn() // this -> undefined |
Some simple examples🤥:
const fn = function(){ console.log(this) } const obj = { fn1: fn, fn2: function() { fn() }, fn3: function(){ this.fn1() }, fn4: fn.bind(obj), fn5: function(){ this.fn1.call(obj) } } obj.fn1() // log: obj // as 'fn1' was invoked via the obj object obj.fn2() // log: window // as 'fn2' was invoked via the obj, but // the inner 'fn' was invoked directly obj.fn3() // log: obj // fn3 was invoked via the obj, 'this' pointed to the // 'obj'. As 'this' -> obj, the inner execution // [this.fn()] is as good // as obj.fn1() obj.fn4() // log: obj // Explicit context binding ;) obj.fn5() // log: obj // hope you're getting a hang of it :P
Some more simple examples 🤥🤥🤥:
function fnConstructor(){ const fn = () => console.log(this) this.fn1 = () => console.log(this), this.fn2 = function(){ console.log(this) } this.fn3 = fn, this.fn4 = function(){ fn() } this.innerObj = { fn } } const obj = new fnConstructor() const obj2 = { obFn1: obj.fn1, obFn2: () => console.log(this) } obj.fn1() // log: obj (Instantiation context!) obj.fn2() // log: obj (Duhh^^) obj.fn3() // log: window ;) obj.fn4() // log: obj (Instantiation context!) obj.innerObj.fn() // log: obj (Instantiation context!!) obj2.obFn1() // log: obj (Instantiation context!!!) obj2.obFn2() // log: window ;)
Hope that was helpful 😇
If you have any questions/confusions/suggestions/corrections, Please do post down in the comments section below.
Top comments (6)
That topmost picture
Made me save it 😜
Marketing 101 😁
😂😂
This is great!
Btw, did you turn on the syntax highlighter for the code snippet? I believe it will make your code snippet more readable :D
Thanks! Yes it did try to enable markdown syntax highlighter but unfortunately markdown code block does not work well with tables, I had to use
<pre>
tags :(obj.fn3() prints the context, if I am not wrong, pls confirm