开发者问题收集

从 asyncThunk 创建的函数调用自定义库时“this”未定义

2023-07-25
83

我创建了一个非常简单的模块,它使用了以下内容:

// log.js
const logger = {

  enabled: false,

  log: (label, value) => {
    let isEnabled = false;
    console.log("BEFORE this");
    try {
      isEnabled = this.enabled;
      console.log("AFTER this");
    }
    catch(err) {
      console.log("ERR calling this ", err);
    }
    if (!isEnabled) {
      return;
    }
    console.log(label, value);
  }
};

export default logger;

我想从 asyncThunk 创建的函数中使用此模块:

import logger from "./log";

export const dqsLogin = createAsyncThunk(
  "user/login",
  async ({username, password}, thunkAPI) => {

    console.log("BEFORE")
    logger.log("TEST:", "test");
    console.log("AFTER")

    // more code...
  }
);

但我在行 isEnabled = this.enabled; 中收到异常。错误显示:“TypeError:无法读取未定义的属性(读取‘enabled’)”。问题是调用中的“this”未定义。

如果用“logger”替换“this”,例如 isEnabled = logger.enabled; ,则库可以按预期工作。但我不想进行这种更改。据说在对象中使用箭头函数可以解决“this”的任何问题。 这里出了什么问题?我不能在库中使用“this”以供 asyncThunk 函数调用吗?

2个回答

您面临的问题与箭头函数如何处理 this 上下文有关。箭头函数没有自己的 this 值;相反,它们从周围的词法范围(创建它们的上下文)继承 this 值。在您的例子中, logger 对象内的箭头函数继承了模块的 this 值,由于模块没有 this 上下文,因此该值是 undefined

要在 logger 对象中使用 this ,您需要对 log 方法使用常规函数声明,而不是箭头函数。以下是 log.js 模块的更新代码:

// log.js
const logger = {
  enabled: false,

  log: function(label, value) { // Use a regular function here, not an arrow function
    let isEnabled = false;
    console.log("BEFORE this");
    try {
      isEnabled = this.enabled;
      console.log("AFTER this");
    } catch(err) {
      console.log("ERR calling this ", err);
    }
    if (!isEnabled) {
      return;
    }
    console.log(label, value);
  }
};

export default logger;

通过使用 常规函数 ,它将绑定到 logger 对象,并且您将能够正确访问 enabled 属性。

Syed Uzair Bukhari
2023-07-25

箭头函数没有 this 关键字绑定。 它们也无法访问 arguments 等。 使用此:

log(label, value) {
    // ...some code
}

有用链接: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

WOWOW
2023-07-25