Understanding the this Binding in JavaScript
This article explains how the this keyword is bound in JavaScript, covering default, implicit, explicit, new, and arrow‑function bindings, and demonstrates the concepts with practical debounce examples and code snippets to show how the calling context determines the value of this.
Preface
The this binding in JavaScript can be confusing for developers who are not deeply involved in front‑end work. This article records the author's recent thoughts and insights about this in anonymous functions, especially when using a debounce utility.
Problem Reproduction
While researching function debouncing, the following code was encountered:
function debounce(fn, delay) {
var timer; // maintain a timer
return function() {
var _this = this; // capture the debounce execution context's this
var args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function() {
fn.apply(_this, args); // apply uses the captured this
}, delay);
};
}Inside the returned anonymous function, the line var _this = this seemed puzzling because the author expected this to refer to the global scope, not the debounce call site.
Experiment
A button element was added to the page and the debounce function was used as an event handler:
<button>我是button</button> // debounce implementation
function debounce(fn, delay) {
var timer; // maintain a timer
return function() {
var _this = this; // capture the execution context's this
var args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function() {
fn.apply(_this, args);
}, delay);
};
}
var btn = document.getElementsByTagName('button')[0];
btn.onclick = debounce(function() {
console.log(this);
}, 1000);Clicking the button logged the button element itself, not window . Adding a global click handler showed that this becomes window when the handler is attached to window , confirming that the value of this depends on the actual caller of the returned function.
Calling Position
The rule "who calls, who this points to" means that the call stack must be examined to determine the real caller. For example:
function foo() {
console.log('foo');
}
function bar() {
console.log('bar');
foo();
}
bar();Setting a breakpoint inside foo and inspecting the stack reveals that bar is the caller.
Default Binding
var a = 2;
function foo() {
var a = 3;
console.log(this.a);
}
foo(); // logs 2 (global object)In non‑strict mode, a plain function call binds this to the global object ( window ). In strict mode, this becomes undefined .
Implicit Binding
var a = 2;
function foo() {
console.log(this.a);
}
var obj1 = { a: 3, foo: foo };
obj1.foo(); // logs 3When a function is invoked as a property of an object, the object becomes the implicit this binding.
Explicit Binding
function foo() {
console.log(this.a);
}
var obj1 = { a: 2 };
var a = 3;
foo.call(obj1); // logs 2Methods like call and apply explicitly set the this value, overriding default or implicit bindings.
new Binding
function Foo(a) {
this.a = a;
}
var bar = new Foo(2);
console.log(bar.a); // logs 2When a function is invoked with new , a fresh object is created and bound to this inside the constructor.
When Bindings Do Not Apply
Arrow functions introduced in ES6 do not follow the four classic binding rules; they inherit this from the surrounding lexical scope.
Summary
The author wrote this article after repeatedly encountering this confusion while reading "You Don't Know JS". The piece outlines the four classic binding rules, shows how closures affect debounce timers, and notes that arrow functions provide a lexical this alternative. Further details on binding loss and priority are left for future updates.
References
"You Don't Know JS"
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.