The Secret Life of JavaScript: Identity
Source: Dev.to
The “Left of the Dot” Rule
Timothy slumped into a chair at the main worktable, dropping his pen onto a piece of code. He looked exhausted.
“I don’t understand who I am anymore, Margaret,” he muttered.
Margaret paused her sorting and walked over.
“That is a deep philosophical question, Timothy.”
“It’s not philosophy. It’s this function,” he said, tapping the paper. “I wrote aprintNamefunction inside myuserobject. When I run it, it prints ‘Timothy’. But when I pass that exact same function to a helper, it forgets who it is. It printsundefined. It’s having an identity crisis.”
Margaret pulled a rolling chalkboard over to the table and picked up a piece of chalk.
“The function is not having a crisis. You are simply assuming that
thisbelongs to the function. It does not.”
She drew a large function on the board.
“In JavaScript, the word
thisis not a fixed label. It is a question. When the code runs, the function looks around and asks: ‘Who called me?’”
Example: Method Call
const user = {
name: "Timothy",
speak: function() {
console.log("My name is " + this.name);
}
};
user.speak();
// ^ Look to the left
// The object 'user' is calling the function.
// Therefore: 'this' is 'user'.
“Look at the last line,” Margaret said, pointing to the dot. “The rule is simple: Look to the left of the dot.”
“The worduseris there,” Timothy replied.
“Exactly. Because you called it throughuser, the function answers the question ‘Who called me?’ with ‘the user.’”
Example: Lost Context
Timothy wrote his bug on the board.
const myFunction = user.speak;
myFunction();
// ^ Look to the left
// There is no dot. There is no object.
// Output: "My name is undefined"
“I didn’t change the code inside!” Timothy argued. “It’s the same function!”
“The code inside didn’t change,” Margaret agreed. “But the call site did.”
“Look to the left ofmyFunction(). Is there a dot? Is there an object?”
“No. It’s just the function name.”
“Precisely. When there is no dot, the function has no owner. In strict mode—which we always use—thisbecomesundefined.”
“And in the old days?”
“It would default to the globalwindowobject—a recipe for disaster.”
Forcing the Context
One‑Time Call with .call()
const stranger = { name: "Margaret" };
// We force `speak` to use `stranger` as `this` right now
user.speak.call(stranger);
// Output: "My name is Margaret"
“With
.call(), you are telling the function: ‘I don’t care where you are. For this one specific execution, your identity is this object.’”
Permanent Binding with .bind()
// We create a NEW function that is permanently locked to `user`
const boundFunction = user.speak.bind(user);
boundFunction();
// Output: "My name is Timothy" (Forever)
“
.bind()does not run the function. It returns a new copy of the function that remembers its owner forever. No matter how you call it later,thiswill always beuser.”
Summary
- Is there a dot? →
thisis the object on the left. - No dot? →
thisisundefined(in strict mode) or the global object (non‑strict). - Used
.call()or.bind()? →thisis whatever you explicitly set.
“I thought this was about where the function lived,” Timothy admitted.
“That is a common mistake,” Margaret said, dusting the chalk from her hands. “In JavaScript, identity is not about who you are. It is about who is holding you at the moment you speak.”