繁体   English   中英

使用 For Loop 而不是 forEach 时出现意外结果

[英]Unexpected result when using For Loop instead of forEach

我正在尝试迭代输入中的选定文件,当我切换以下语句时,我遇到了一个奇怪的错误

Object.keys(event.target.files).forEach(key => {
   const currentFile = event.target.files[key]
}

for (let key in event.target.files) {
   const currentFile = event.target.files[key]
}  

我不明白这两个语句之间有什么区别,第一个有效,但第二个无效(导致奇怪的错误,循环内的 object 变为 null。

这是完整的代码:

onChange= (event) => {
        const selectedFilesObject = event.target.files
        let selectedFilesCount = Object.keys(selectedFilesObject).length

        if (selectedFilesCount > 0) {
            this.setState({ loading: true })
            this.props.onLockdownChange(true)

            let readFilesResult = {}

            for (let key in selectedFilesObject) {
                const currentFile = selectedFilesObject[key]

                readFileAsByteArray(currentFile)
                    .then(response => {
                        readFilesResult[key] = {
                            bytes: response,
                            name: currentFile.name,
                            type: currentFile.type,
                        }
                    })
                    .catch(() => {
                        readFilesResult[key] = null                        
                    })
                    .finally(() => {
                        selectedFilesCount = selectedFilesCount - 1
                        if (selectedFilesCount === 0) {
                            this.onReadingFilesFinished(readFilesResult)
                        }
                    })
            }
        }
    }  


export const readFileAsByteArray = (file) => {
    return new Promise((resolve, reject) => {
        var reader = new FileReader();
        var fileByteArray = [];
        reader.readAsArrayBuffer(file);
        reader.onloadend = (evt) => {
            if (evt.target.readyState == FileReader.DONE) {
                var arrayBuffer = evt.target.result,
                    array = new Uint8Array(arrayBuffer);
                for (var i = 0; i < array.length; i++) {
                    fileByteArray.push(array[i]);
                }

                resolve(fileByteArray)
            }
        }

        reader.onerror = error => {
            reject()
        };
    })
}  

我只需要了解为什么使用 for 循环会导致readFilesResult具有 null 长度! 但使用object.keys().forEach不会!

您在这里枚举了一个FileList ,它作为一个 DOM 集合具有itemlength属性。 您不应该在此处使用Object.keysfor … in循环,而应像在任何类似数组的 object 上那样使用for (let i=0; i<files.length; i++)迭代。 另请参阅为什么在 arrays 上使用for…in是个坏主意? .

或者直接将其转换为数组:

onChange = (event) => {
    const selectedFiles = Array.from(event.target.files)
//                        ^^^^^^^^^^
    if (selectedFiles.length > 0) {
        this.setState({ loading: true })
        this.props.onLockdownChange(true)

        Promise.all(selectedFiles.map(currentFile =>
            readFileAsByteArray(currentFile).then(response => ({
                bytes: response,
                name: currentFile.name,
                type: currentFile.type,
            }), err => null)
        )).then(readFilesResult => {
            this.onReadingFilesFinished(readFilesResult)
        })
    }
}

这两个循环之间的区别归结为 object 是否实际上具有属性,或者继承了属性。

例如,如果您有一个继承了属性的 object; Object.keys不会返回它,但 for in 循环会。 这就是为什么您需要为 for in 循环中的每个键调用hasOwnProperty方法。

以更详细的方式; for in 循环不受原型链的困扰。

// lets create a class called "Example".

class Example{
   constructor(a,b) {
      this.a = a;
      this.b = b;
   }
}

let instance = new Example(1,2);
for(let key in instance) {
    console.log(key); // will only print "a" and "b". Which is to be expected.
}

// Let's add a member to all of the objects that are instantiated from the class Example using Example's prototype.

Example.prototype.newMember = "I exist";

// Let's run the for in loop again

for(let key in instance) {
    console.log(key); // Prints "a", "b", and "newMember". The instances that are coming from "Example" doesn't have this... What happened there?
}

结果是,当您运行 for-in 循环时,该循环无法识别原型属性,并在所有这些属性上运行。 这就是为什么我建议对您的示例运行hasOwnProperty检查。 hasOwnProperty检查该成员是否确实具有属性,或者它是否是原型属性。

这有任何意义吗?

暂无
暂无

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

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