简体   繁体   English

“'x' is not a function or its return value is not iterable”的含义错误

[英]The meaning of “'x' is not a function or its return value is not iterable” error

I accidentally witnessed that this causes an error in V8 (Chrome, Node.js, etc):我无意中看到这会导致 V8 出现错误(Chrome、Node.js 等):

for (let val of Symbol()) { /*...*/ }

TypeError: Symbol is not a function or its return value is not iterable TypeError: Symbol is not a function or its return value is not iterable

It appears that any other non-iterable value (including a function) causes another error:似乎任何其他不可迭代的值(包括函数)都会导致另一个错误:

for (let val of function () { throw 'never called' }) { /*...*/ }

TypeError: (intermediate value) is not iterable TypeError:(中间值)不可迭代

As the reference states, the error is specific to Chrome:正如参考资料所述,该错误特定于 Chrome:

TypeError: 'x' is not a function or its return value is not iterable (Chrome) TypeError:'x' 不是 function 或其返回值不可迭代(Chrome)

... ...

The value which is given as the right hand-side of for…of or as argument of a function such as Promise.all or TypedArray.from, is not an iterable object.作为 for…of 的右侧或作为 function (例如 Promise.all 或 TypedArray.from)的参数给出的值不是可迭代的 ZA8CFDE6331BD59EB2AC96F8911C4B66 An iterable can be a built-in iterable type such as Array, String or Map, a generator result, or an object implementing the iterable protocol.可迭代对象可以是内置可迭代类型,例如 Array、String 或 Map、生成器结果或实现可迭代协议的 object。

It seems that none of listed things are expected to accept a function instead of iterable as an argument so it's unclear why the error puts emphasis on function type.似乎所有列出的东西都不会接受 function 而不是 iterable 作为参数,所以不清楚为什么错误强调 function 类型。

Is there any meaning to this error?这个错误有什么意义吗? Are there circumstances under which is not a function remark makes sense in its context?是否存在is not a function评论在其上下文中有意义的情况?

Yes, there is meaning to both parts of the error message.是的,错误消息的两个部分都有意义。 In the case you have at hand, the return value of Symbol() is not iterable, so that's the second option.在您手头的情况下, Symbol()的返回值是不可迭代的,所以这是第二个选项。 As an example for the first option, just take something that's not a function:作为第一个选项的示例,只需使用不是 function 的东西:

let NotAFunction = {};  // Or any other object.
for (let val of NotAFunction()) {}

gives: Uncaught TypeError: NotAFunction is not a function or its return value is not iterable .给出: Uncaught TypeError: NotAFunction is not a function or its return value is not iterable In this case, clearly, NotAFunction is not a function;-)在这种情况下,显然NotAFunction不是 function;-)

I don't know why there aren't two separate error messages for "it's not a function at all" and "it was a function and it's been called, but its return type wasn't iterable".我不知道为什么没有两条单独的错误消息分别表示“它根本不是 function”和“它是 function 并且它已被调用,但它的返回类型不可迭代”。 Presumably something in the internal logic to implement for..of loops made it prohibitively complicated to have finer-grained error reporting -- so the combined error message simply mentions two possible reasons why the loop didn't work.据推测,实现for..of循环的内部逻辑中的某些东西使得更细粒度的错误报告变得异常复杂——所以组合的错误消息只是提到了循环不起作用的两个可能原因。

The for..of operator pass an argument to a variable trough the iterator protocol. for..of 运算符通过迭代器协议将参数传递给变量。

The iterator protocol specifies the needs of @@iterator method to work, so, if the function, object or a class doesn't have the Symbol.iterator/Symbol.asyncIterator implemented it will throw this error.迭代器协议指定了@@iterator方法工作的需要,所以,如果 function、object 或 class 没有 Symbol.iterator/SymbolIteratorIterator 实现的错误。

On the first case, the Symbol it's a constant, so it's not iterable.在第一种情况下, Symbol 它是一个常量,所以它是不可迭代的。 On the second, the value trowed it's a intermediate value, this means that the VM can't do a conversion to a iterable type(arrays, objects, classes or functions with the iterator method), that is, it can't be executed to get a result due to the fact that the for..of is expecting an implementation of the @@iterator method.第二个,它的值是一个中间值,这意味着VM无法转换为可迭代类型(使用迭代器方法的数组,对象,类或函数),即无法执行由于 for..of 期望实现 @@iterator 方法而得到结果。

The emphasis comes due the fact that iterator is a function that have the @@iterator method.重点来自于迭代器是具有@@iterator 方法的 function 的事实。 eg:例如:


const someIterator = {};
someIterator[Symbol.iterator] = function(names) {
    return {
        next() {
            this.index = 0;
            yield names[index];
            this.index = this.index++;
        }
    }
}

Printing:印刷:

{[Symbol.iterator]: [Function (anonymous)]}

The expected method of an for..of loop is a iterator function. for..of 循环的预期方法是迭代器 function。 So, the error message will empathize that is expecting a function.因此,错误消息会让人感同身受,期待 function。

To implement the method, you can do the same thing above, using ES6 classes, or with objects(accessing trough the key), prototype functions, or just a generator.要实现该方法,您可以使用 ES6 类或对象(通过键访问)、原型函数或仅使用生成器来执行上述相同的操作。

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

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