简体   繁体   English

类声明中未定义的超级方法

[英]super method undefined in class declaration

TL;DR - The super keyword in my class declaration is sometimes (but not always) undefined. TL; DR- 我的类声明中的super关键字有时(但并非总是)未定义。 How/why? 如何/为什么?

I have the following class declaration extending Array used for search result data from an API: 我有以下类声明,扩展了用于从API搜索结果数据的Array

class SearchResult extends Array {
  constructor(resultArray) {
    super(...resultArray);
  }

  static createFromApiData(apiData) {
    const resultArray = apiData.filter(...).map(...);
    return new SearchResult(resultArray);
  }

  ...otherMethods

}

In my app this is initially called immediately on receiving the response from the API, like below: 在我的应用中,这是在收到来自API的响应后立即调用的,如下所示:

apiCall().then((res) => {
  const searchResults = SearchResult.createFromApiData(res.data);
});

Creating a new SearchResult instance using this static method works correctly, returning what I want. 使用此静态方法创建新的SearchResult实例可以正常工作,并返回我想要的内容。

However, later in my app I need to create a SearchResult instance again, this time there is no need for an API call as I already have the resultArray data stored in a database. 但是,稍后在我的应用程序中,我需要再次创建SearchResult实例,这一次无需进行API调用,因为我已经将resultArray数据存储在数据库中。 Therefore the second time around I try to create the instance of SearchResult using the new keyword like below: 因此,第二次尝试使用以下new关键字创建SearchResult实例:

const searchResults = new SearchResult(resultArray);

This time, using the new keyword the instance creation fails throwing the following error: 这次,使用new关键字创建实例失败,并引发以下错误:

TypeError: undefined is not a function at new SearchResult

I know undefined in this context is referring to the super keyword but I can not understand why this is the case? 我知道在这种情况下undefined是指super关键字,但我不明白为什么会这样? How can the instance creation behaviour vary in these two cases? 在这两种情况下,实例创建行为如何变化? How can I fix it? 我该如何解决?


UPDATE UPDATE

I've investigated further and found the following. 我进行了进一步调查,发现以下内容。 My initial issue was caused because I was saving my custom SearchResult class instance to the database ( dynamodb ). 我的最初问题是由于将自定义SearchResult类实例保存到数据库( dynamodb )引起的。 Although SearchResult extended array, ddb saved it as a basic object, so on retrieval of the data from the database it came in basic object, not array form. 尽管SearchResult扩展了数组,但ddb将其保存为基本对象,因此从数据库中检索数据时,它以基本对象而不是数组形式出现。 This then threw an error when I attempted to spread the object inside inside the super function. 当我尝试在super函数内部扩展对象时,这将引发错误。

I resolved this by spreading my class instance in a new array when saving it to ddb : 我通过将类实例保存到ddb时将其类实例散布在新数组中来解决此问题:

db.save([...searchResults]);

This returned an array after database recall and could be successfully spread inside the super call. 在数据库重新调用后,此方法返回一个数组,并且可以在super调用中成功传播。

However, this has lead to a new issue. 但是,这导致了一个新问题。 Immediately after creating the new SearchResult instance I call a the following custom method on it: 创建新的SearchResult实例后,立即在其上调用以下自定义方法:

nextItem() {
  this.splice(0, 1);
  return this[0];
}

This method then again calls super to access the splice method on Array . 然后,此方法再次调用super以访问Array上的splice方法。 However, once again this fails throwing the same error as before: 但是,这再次引发与以前相同的错误:

{
  "errorMessage": "undefined is not a function",
  "errorType": "TypeError",
  "stackTrace": [
    "new SearchResult",
    "SearchResult.splice",
    "SearchResult.nextRecipe"
}

Once again this is referring to the spread operation inside super . 再一次,这是指super内的传播操作。 This time super is being passed the number 1 as its sole argument. 这次super被传递数字1作为唯一参数。 Where is is this 1 coming from and how can I fix it? 1是哪里来的,我该如何解决?


UPDATE 2 更新2

After updating the class method to us shift instead of splice the method now works correctly without errors. 更新类的方法给我们后shift ,而不是splice的方法,现在可以正常工作没有错误。 My problem is now effectively solved, however I would still appreciate insight on what the issue of super being called with 1 was about with splice . 我的问题是现在有效地解决了,但是我仍然会欣赏什么问题的洞察力super被称为具有1是关于与splice Why would these two array methods behave differently in this context. 为什么这两个数组方法在这种情况下会有不同的表现。

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? 我知道在这种情况下undefined是指super关键字,但我不明白为什么会这样?

Probably not. 可能不是。 super refers to the internal unchangeable [[HomeObject]] property of the class, that gets set when the class gets declared, you can't modify that, you can only rewrite the class itself, eg: super该类的内部不可更改的[[HomeObject]]属性,该属性在声明该类时设置,您不能修改它,只能重写该类本身,例如:

 SearchResult = function() { undefined(); }

But I guess you don't do that. 但是我猜你不会那样做。

But where does the error come from? 但是错误是从哪里来的呢?

Well there are two things happening in that line: 好吧,在这一行中发生了两件事:

 super(...resultArray);

One is the super() call and the other one is the spreading of the resultArray , which will create and consume an iterator of the resultArray which is barely equal to: 一个是super()调用,另一个是resultArray的扩展,这将创建并使用resultArray的迭代器,该迭代器几乎不等于:

 resultArray[Symbol.iterator]()

and if the iterator does not exist (because you accidently passed a non array to the constructor) it fails, saying that the iterator can't be called: 如果迭代器不存在(因为您不小心将非数组传递给了构造函数),它将失败,并指出无法调用迭代器:

 var resultArray = {};

 resultArray[Symbol.iterator]()
 // equals:
 undefined()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM