Consider the following code:
function createUser() { return { name: "John Doe", ref: this }; } let user = createUser(); alert( user.ref.name ); // What's the result?
What is the result of accessing its ref? Why?
The result is an error.
function createUser() { return { name: "John Doe", ref: this }; } let user = createUser(); alert(user.ref.name); // Error: Cannot read property 'name' of undefined
This occurs because the rules governing this
do not consider object definitions. Instead, they depend on the moment of function invocation.
Within the createUser()
function, the value of this
is undefined
because it is invoked as a function, not as a method with dot syntax.
The value of this
remains consistent throughout the entire function, unaffected by code blocks or object literals. Therefore, ref: this
captures the current this
of the function.
We can rewrite the function to explicitly return this
:
function createUser(){ return this; // In this version, there's no object literal } alert(createUser().name); // Error: Cannot read property 'name' of undefined
Notice that the result of alert(createUser().name)
mirrors the outcome of alert(user.ref.name)
from the previous example.
Alternatively, when ref
is defined as a method, this
is properly bound:
function createUser() { return { name: "John Doe", ref() { return this; } }; } let user = createUser(); alert(user.ref().name); // John Doe
Here, user.ref()
acts as a method, and this
is correctly set to the object before the dot.