You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中如何在类内捕获调用者的原始this指向

Fixing this Context When Passing Class Methods as Callbacks

Let's break down why your code is behaving that way first: when you pass abc.funcAbc to the Def constructor, you're just passing a reference to the function itself—it loses its original this binding to the abc instance. When def.runFunc() calls this.func(), this inside funcAbc defaults to the caller (the def instance) because of how function invocation works in JavaScript.

Here are 3 straightforward ways to fix this and make this point to the original Abc instance:

1. Explicitly Bind the Context with bind()

The bind() method creates a new function that permanently binds this to the specified value. Just bind abc.funcAbc to the abc instance before passing it to Def:

class Abc {
  funcAbc() {
    console.log(this); // Now logs the Abc instance
  }
}
const abc = new Abc();
class Def {
  constructor(func) {
    this.func = func;
  }
  runFunc() {
    this.func();
  }
}
// Bind funcAbc to the abc instance
const def = new Def(abc.funcAbc.bind(abc));
def.runFunc();

2. Wrap the Method in an Arrow Function

Arrow functions don't have their own this—they inherit the this value from the surrounding lexical context. By wrapping abc.funcAbc() in an arrow function, you preserve the original context:

// ... (keep Abc and Def classes the same)
const abc = new Abc();
// Pass an arrow function that calls funcAbc on abc
const def = new Def(() => abc.funcAbc());
def.runFunc(); // Logs the Abc instance

3. Define the Method as an Arrow Function in the Class

If you want funcAbc to always bind to the Abc instance (no matter where it's passed), define it as a class field using an arrow function. This captures the instance's this when the class is instantiated:

class Abc {
  // Use an arrow function class field to bind this permanently
  funcAbc = () => {
    console.log(this); // Logs the Abc instance
  }
}
const abc = new Abc();
class Def {
  constructor(func) {
    this.func = func;
  }
  runFunc() {
    this.func();
  }
}
// No extra binding needed now
const def = new Def(abc.funcAbc);
def.runFunc();

Quick Notes on Each Approach:

  • bind() is great for one-off bindings where you need to reuse the same function reference with a fixed context.
  • Arrow function wrapping is flexible if you need to add extra logic when calling the method.
  • Class field arrow functions are ideal if the method should always be tied to its instance (but note this adds the function directly to each instance instead of the prototype).

内容的提问来源于stack exchange,提问作者darKnight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:16:01