class 声明中未定义超级方法
super method undefined in class declaration
TL;DR - 我的 class 声明中的 super 关键字有时(但不总是)未定义。 How/why?
我有以下 class 扩展 Array
的声明,用于来自 API 的搜索结果数据:
class SearchResult extends Array {
constructor(resultArray) {
super(...resultArray);
}
static createFromApiData(apiData) {
const resultArray = apiData.filter(...).map(...);
return new SearchResult(resultArray);
}
...otherMethods
}
在我的应用程序中,最初会在收到 API 的响应时立即调用它,如下所示:
apiCall().then((res) => {
const searchResults = SearchResult.createFromApiData(res.data);
});
使用此静态方法创建新的 SearchResult
实例工作正常,返回我想要的。
但是,稍后在我的应用程序中我需要再次创建一个 SearchResult
实例,这次不需要 API 调用,因为我已经存储了 resultArray
数据在数据库中。因此,我第二次尝试使用 new
关键字创建 SearchResult
的实例,如下所示:
const searchResults = new SearchResult(resultArray);
这一次,使用 new
关键字实例创建失败并抛出以下错误:
TypeError: undefined is not a function at new SearchResult
我知道 undefined
在此上下文中指的是 super
关键字,但我不明白为什么会这样?在这两种情况下,实例创建行为有何不同?我该如何解决?
更新
我进一步调查并发现了以下内容。我最初的问题是因为我将自定义 SearchResult
class 实例保存到数据库 (dynamodb)。尽管 SearchResult
扩展数组,ddb 将其保存为基本对象,因此在从数据库中检索数据时,它以基本对象形式出现,而不是数组形式。当我试图在 super
函数内传播对象时,这会引发错误。
我通过将 class 实例保存到 ddb:
时将其分散到一个新数组中来解决这个问题
db.save([...searchResults]);
这在数据库调用后返回了一个数组,可以在 super
调用中成功传播。
但是,这导致了一个新问题。在创建新的 SearchResult
实例后,我立即对其调用了以下自定义方法:
nextItem() {
this.splice(0, 1);
return this[0];
}
此方法然后再次调用 super
以访问 Array
上的 splice
方法。然而,这又一次失败,抛出与以前相同的错误:
{
"errorMessage": "undefined is not a function",
"errorType": "TypeError",
"stackTrace": [
"new SearchResult",
"SearchResult.splice",
"SearchResult.nextRecipe"
}
这又是指 super
中的传播操作。这次 super
被传递给数字 1
作为它唯一的参数。这个 1
是从哪里来的,我该如何解决它?
更新 2
在将 class 方法更新给我们 shift
而不是 splice
之后,该方法现在可以正常工作,没有错误。我的问题现在已得到有效解决,但我仍然希望了解 1
调用 super
的问题与 splice
的关系。为什么这两个数组方法在这种情况下表现不同。
nextItem() {
return this.shift();
}
I know undefined in this context is referring to the super keyword but I can not understand why this is the case?
可能不会。 super
指的是 class 的内部不可更改的 [[HomeObject]] 属性,它在声明 class 时设置,你不能修改它,你可以只重写 class 本身,例如:
SearchResult = function() { undefined(); }
但我猜你不会那样做。
但是错误从何而来?
那一行中发生了两件事:
super(...resultArray);
一个是 super()
调用,另一个是 resultArray
的传播,它将创建并使用 resultArray
的迭代器,它几乎等于:
resultArray[Symbol.iterator]()
如果迭代器不存在(因为你不小心传递了一个非数组给构造函数)它失败了,说迭代器不能被调用:
var resultArray = {};
resultArray[Symbol.iterator]()
// equals:
undefined()
TL;DR - 我的 class 声明中的 super 关键字有时(但不总是)未定义。 How/why?
我有以下 class 扩展 Array
的声明,用于来自 API 的搜索结果数据:
class SearchResult extends Array {
constructor(resultArray) {
super(...resultArray);
}
static createFromApiData(apiData) {
const resultArray = apiData.filter(...).map(...);
return new SearchResult(resultArray);
}
...otherMethods
}
在我的应用程序中,最初会在收到 API 的响应时立即调用它,如下所示:
apiCall().then((res) => {
const searchResults = SearchResult.createFromApiData(res.data);
});
使用此静态方法创建新的 SearchResult
实例工作正常,返回我想要的。
但是,稍后在我的应用程序中我需要再次创建一个 SearchResult
实例,这次不需要 API 调用,因为我已经存储了 resultArray
数据在数据库中。因此,我第二次尝试使用 new
关键字创建 SearchResult
的实例,如下所示:
const searchResults = new SearchResult(resultArray);
这一次,使用 new
关键字实例创建失败并抛出以下错误:
TypeError: undefined is not a function at new SearchResult
我知道 undefined
在此上下文中指的是 super
关键字,但我不明白为什么会这样?在这两种情况下,实例创建行为有何不同?我该如何解决?
更新
我进一步调查并发现了以下内容。我最初的问题是因为我将自定义 SearchResult
class 实例保存到数据库 (dynamodb)。尽管 SearchResult
扩展数组,ddb 将其保存为基本对象,因此在从数据库中检索数据时,它以基本对象形式出现,而不是数组形式。当我试图在 super
函数内传播对象时,这会引发错误。
我通过将 class 实例保存到 ddb:
时将其分散到一个新数组中来解决这个问题db.save([...searchResults]);
这在数据库调用后返回了一个数组,可以在 super
调用中成功传播。
但是,这导致了一个新问题。在创建新的 SearchResult
实例后,我立即对其调用了以下自定义方法:
nextItem() {
this.splice(0, 1);
return this[0];
}
此方法然后再次调用 super
以访问 Array
上的 splice
方法。然而,这又一次失败,抛出与以前相同的错误:
{
"errorMessage": "undefined is not a function",
"errorType": "TypeError",
"stackTrace": [
"new SearchResult",
"SearchResult.splice",
"SearchResult.nextRecipe"
}
这又是指 super
中的传播操作。这次 super
被传递给数字 1
作为它唯一的参数。这个 1
是从哪里来的,我该如何解决它?
更新 2
在将 class 方法更新给我们 shift
而不是 splice
之后,该方法现在可以正常工作,没有错误。我的问题现在已得到有效解决,但我仍然希望了解 1
调用 super
的问题与 splice
的关系。为什么这两个数组方法在这种情况下表现不同。
nextItem() {
return this.shift();
}
I know undefined in this context is referring to the super keyword but I can not understand why this is the case?
可能不会。 super
指的是 class 的内部不可更改的 [[HomeObject]] 属性,它在声明 class 时设置,你不能修改它,你可以只重写 class 本身,例如:
SearchResult = function() { undefined(); }
但我猜你不会那样做。
但是错误从何而来?
那一行中发生了两件事:
super(...resultArray);
一个是 super()
调用,另一个是 resultArray
的传播,它将创建并使用 resultArray
的迭代器,它几乎等于:
resultArray[Symbol.iterator]()
如果迭代器不存在(因为你不小心传递了一个非数组给构造函数)它失败了,说迭代器不能被调用:
var resultArray = {};
resultArray[Symbol.iterator]()
// equals:
undefined()