typescript 为什么 NodeListOf 上不存在 forEach

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47492595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:04:08  来源:igfitidea点击:

Why forEach does not exist on NodeListOf

javascripttypescript

提问by cyan

My code:

我的代码:

    var checkboxes = this.element.querySelectorAll("input[type=checkbox]") as NodeListOf<HTMLInputElement>;
    checkboxes.forEach(ele => {
        var key = ele.name;
        if (data.hasOwnProperty(key)) {
            if (!this.isArray(data[key])) {
                var temp = data[key];
                data[key] = [temp];
            }
        } else {
            data[key] = [];
        }
    });

But I got an error:

但我得到了一个错误:

error TS2339: Property 'forEach' does not exist on type 'NodeListOf'.

错误 TS2339:类型“NodeListOf”上不存在属性“forEach”。

interface NodeListOf<TNode extends Node> extends NodeList {
    length: number;
    item(index: number): TNode;
    [index: number]: TNode;
}

interface NodeList {
    /**
     * Returns an array of key, value pairs for every entry in the list
     */
    entries(): IterableIterator<[number, Node]>;
    /**
     * Performs the specified action for each node in an list.
     * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the list.
     * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
     */
    forEach(callbackfn: (value: Node, index: number, listObj: NodeList) => void, thisArg?: any): void;
    /**
     * Returns an list of keys in the list
     */
    keys(): IterableIterator<number>;

    /**
     * Returns an list of values in the list
     */
    values(): IterableIterator<Node>;


    [Symbol.iterator](): IterableIterator<Node>;
}

'NodeListOf' inherit from 'NodeList',and 'NodeList' has 'forEach' method,why 'forEach' does not exist on 'NodeListOf'?

“NodeListOf”继承自“NodeList”,“NodeList”有“forEach”方法,为什么“NodeListOf”上不存在“forEach”?

回答by Daniel Kucal

There is no guarantee forEachwill exist on this type - it can, but not necessarily (e.g. in PhantomJS and IE), so TypeScript disallows it by default. In order to iterate over it you can use:

不能保证forEach这种类型会存在 - 它可以,但不一定(例如在 PhantomJS 和 IE 中),因此默认情况下 TypeScript 不允许它。为了迭代它,您可以使用:

1) Array.from():

1) Array.from():

Array.from(checkboxes).forEach((el) => { /* do something */});

2) for-in:

2) 换入:

for (let i in checkboxes) {
  if (checkboxes.hasOwnProperty(i)) {
    console.log(checkboxes[i]);
  }
}

回答by Tommy May

Honestly you couldconvert a NodeListOf to an array so that typescript will not complain about nodelist.forEach, but this is only solving the problem by adding unnecessary code. You can tell typescript to understand the native nodelist.forEach syntax by adding the dom.iterablelibrary to your tsconfig.json. Here is an example of one of my tsconfig.json files.

老实说,您可以将 NodeListOf 转换为数组,这样打字稿就不会抱怨nodelist.forEach,但这只是通过添加不必要的代码来解决问题。您可以通过将dom.iterable库添加到您的 tsconfig.json来告诉打字稿理解本机nodelist.forEach 语法。这是我的 tsconfig.json 文件之一的示例。

{
  "compilerOptions": {
  "outDir": "./public/js/",
  "noImplicitAny": true,
  "module": "es6",
  "target": "es5",
  "allowJs": true,
  "moduleResolution": "node",
  "rootDir": "src",
  "lib": [
    "es6",
    "dom",
    "dom.iterable"
  ],
  "typeRoots": [
    "node_modules/@types"
  ],
  "removeComments": false
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules",
    "public",
    "**/*.spec.ts"
  ]
}

Not all browsers support nodelist.forEach so I would definitely polyfill it https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach

并非所有浏览器都支持nodelist.forEach 所以我肯定会对其进行 polyfill https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach