关于JavaScript箭头函数this绑定与作用域的困惑:为何能访问外层this?
test's this.a? Great question—let’s unpack this behavior step by step to clear up your confusion. The key here lies in how arrow functions handle this versus regular functions.
First, Let’s Recap Arrow Function this Rules
Unlike regular functions, arrow functions do not have their own this binding. Instead, they inherit this from the lexical scope where they are defined (the scope they were written in), not from how they’re called. This is a critical difference from regular functions, whose this is determined entirely by their invocation context.
Breaking Down Your Code
Let’s walk through exactly what happens when your code runs:
var d = new test();: When you use thenewkeyword, it creates a new object, and thethisinside thetestfunction points directly to this new object (which becomesd). Sothis.a = 5setsd.a = 5.d.b();: When you callbviad.b(), thethisinside thebfunction also points tod(because regular functions called as object methods havethisbound to the object).- The Arrow Function in
setTimeout: The arrow function() => { console.log(this.a); }is defined inside thebfunction. Since arrow functions inheritthisfrom their lexical scope, it takes thethisvalue fromb—which isd. That meansthis.ainside the arrow function is exactlyd.a, which is 5.
Why Your Initial Assumption Was Off
You thought the lookup would stop at the regular b function layer, but that’s not how arrow functions work. Arrow functions don’t create their own this context, so they don’t “block” the lookup—they just reuse the this from the surrounding scope where they were defined. In this case, that surrounding scope’s this is the test instance (d), so it can access d.a directly.
A Quick Contrast: Regular Function in setTimeout
If you replaced the arrow function with a regular function:
setTimeout(function() { console.log(this.a); // Undefined (in browser, `this` would default to `window`) }, 1000);
Here, the regular function has its own this binding, which defaults to window (in non-strict mode) because setTimeout calls it as a global function. This is why it wouldn’t find a—but arrow functions avoid this by inheriting the lexical this.
内容的提问来源于stack exchange,提问作者user2924127

