I was learning about the this keyword and how it means different things with regards to regular functions vs ES6 arrow functions and function expressions and I came across something odd when trying to run the following code in Chrome, Deno and Node. So I prepared following:
Example:
function foo(n) {
console.log("***Begin Foo****")
console.log(`n = ${n}\nthis = ${this}\nthis.count = ${this.count}`)
console.log("****End Foo****")
this.count++;
}
var count = 1;
for (let i = 0; i < 5 ; ++i) {
foo(i)
}
console.log("From global this.count = "+this.count)
console.log(this)
Deno output:
PS E:\webdev\js_scratchspace> deno run .\another_this.js
***Begin Foo****
error: Uncaught TypeError: Cannot read property 'count' of undefined
console.log(`n = ${n}\nthis = ${this}\nthis.count = ${this.count}`)
^
at foo (file:///E:/webdev/js_scratchspace/another_this.js:24:64)
at file:///E:/webdev/js_scratchspace/another_this.js:31:5
Node output:
PS E:\webdev\js_scratchspace> node .\another_this.js
***Begin Foo****
n = 0
this = [object global]
this.count = undefined
****End Foo****
***Begin Foo****
n = 1
this = [object global]
this.count = NaN
****End Foo****
***Begin Foo****
n = 2
this = [object global]
this.count = NaN
****End Foo****
***Begin Foo****
n = 3
this = [object global]
this.count = NaN
****End Foo****
***Begin Foo****
n = 4
this = [object global]
this.count = NaN
****End Foo****
From global this.count = undefined
{}
Chrome output:
***Begin Foo****
n = 0
this = [object Window]
this.count = 1
****End Foo****
***Begin Foo****
n = 1
this = [object Window]
this.count = 2
****End Foo****
***Begin Foo****
n = 2
this = [object Window]
this.count = 3
****End Foo****
***Begin Foo****
n = 3
this = [object Window]
this.count = 4
****End Foo****
***Begin Foo****
n = 4
this = [object Window]
this.count = 5
****End Foo****
From global this.count = 6
Window {window: Window, self: Window, document: document, name: '', location: Location, …}
According to my understanding of this, where for arrow functions this has no explicit binding and refers to the scope's this in which the arrow function was defined, whereas for regular functions this refers to the context from which it was invoked, Chrome's output seems to make the most sense to me. I don't understand why for example, Node would not recognize the global object as this. I am least bothered by Deno's output as I guess I may not understand what it's trying to do exactly.
Can someone explain why Node, Deno and Chrome are giving me different outputs?