Reasonable twisting implied this access.
x = {}
function f1 () {
this.v1 = 'cool'
try { console.log('v1:', v1) } catch(e){ console.log('error') }
}
f1.bind(x)()
f1()
f1.bind(x)()
f1()
Output:
error
v1: cool
v1: cool
v1: cool
Please explain why this code prints error
once and then cool
.
Why does it work v1
without it this
at all?
At first, you do not register this.v1
, but simply v1
. This is a reference to a global variable v1
that should be defined on window
. Every time you register not x.v1
, but window.v1
.
this
in a non-scoped function, it is global window
. So when you call it the first time it v1
is created on x
, but when you call it the second time it is created on window
.
The second call, f1()
without bind()
- where this
implicitly window
, assigns a global variable v1
(or window.v1
) 'cool'
, and this is the value that is printed later.
Interest Ask.
Why can you use v1 without this keyword?
Because your "this" keyword will bind to the "window" object, which is special. In the case of a window, the variable object is the same as the "this" object / context.
Simply put, the variables and properties of the window object are the same thing.
Below is an example from ECMA-262.
var a = new String('test');
alert(a); // directly, is found in VO(globalContext): "test"
alert(window['a']); // indirectly via global === VO(globalContext): "test"
alert(a === this.a); // true
var aKey = 'a';
alert(window[aKey]); // indirectly, with dynamic property name: "test"