Javascript &引用;这";嵌套函数上的关键字应用

Javascript &引用;这";嵌套函数上的关键字应用,javascript,nested,this,anonymous-function,Javascript,Nested,This,Anonymous Function,我有以下代码: <!DOCTYPE html> <html> <head> <title>Drag-Drop tests</title> <meta charset="UTF-8"> </head> <body> <script> var body = document.b

我有以下代码:

<!DOCTYPE html>

<html>
    <head>
        <title>Drag-Drop tests</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <script>
            var body = document.body;
            
            var cursor = document.createElement("div");
            cursor.innerText = "Contenus des fichiers :\n";
            
            cursor.ondragover = e => e.preventDefault();
            cursor.ondrop = function(e) {
                e.preventDefault();
                
                if (e.dataTransfer.items) {
                    for (var i = 0; i < e.dataTransfer.items.length; i++) {
                        if (e.dataTransfer.items[i].kind === "file") {
                            var file = e.dataTransfer.items[i].getAsFile();
                            
                            file.cursor = document.createElement("p");
                            body.appendChild(file.cursor);
                            
                            file.cursor.innerText = file.name + " contient :";
                            
                            file.text().then(function(value) {
                                file.cursor.innerText += " " + value;
                            });
                        }
                    }
                }
                else {
                    for(var i = 0; i < e.dataTransfer.files.length; i++) {
                        var file = e.dataTransfer.files[i];
                            
                        file.cursor = document.createElement("p");
                        body.appendChild(file.cursor);
                        
                        file.cursor.innerText = file.name + " contient :";
                        
                        file.text().then(function(value) {
                            file.cursor.innerText += " " + value;
                        });
                    }
                }
            };
            
            body.appendChild(cursor);
        </script>
    </body>
</html>
在file.text()函数中,“file”是指最后声明的文件引用

如果我替换 file.cursor.innerText+=按 this.cursor.innerText+= 我得到这个输出:

Contenus des fichiers :

File1.txt contient :

File2.txt contient : Content of file 1 Content of file 2
Contenus des fichiers :
Content of file 1 Content of file 2

File1.txt contient :

File2.txt contient :
在file.text().then函数中,“this”指的是第一个调用方,即div本身

有什么办法可以做到这一点:

Contenus des fichiers :

File1.txt contient : Content of file 1

File2.txt contient : Content of file 2
将匿名嵌套函数保留为调用者的参数

我知道在我定义它的回调时,不会发生这种情况。 我想知道我是否可以附上一些数据 并在回调执行时检索该对象

Thx由advance执行。

.text()
是异步的。所有
.then()
都发生在整个
for
循环结束之后。非常经典的异步循环操作问题。您只需要等待,而不是使用(老式的)
.then()
语法

cursor.ondrop = async function(e) {
     // ...
     for(...) {
         const value = await file.text();
         file.cursor.innerText += " " + value;
     }
}
JSFiddle:

您之所以得到这个结果,是因为在承诺执行之后发生了
+=''+值。换句话说,在您的示例代码中,会发生以下步骤:

  • 将“文件1 contient”添加到div
  • 开始读取文件1
  • 在div中添加“File2 contient”
  • 开始读取文件2
  • […]过了一会儿

  • file1读取已完成,因此承诺已解决,file1的内容将附加到div
  • file2读取已完成,因此承诺已解决,file2的内容将附加到div中
  • 在这种特殊情况下,它还与for循环中更改的
    file
    变量的范围有关,因此在promise1解析时,
    file
    已经引用了第二段,因此
    file.cursor.innerText
    引用了第二段的内容

    而不是:

    file.cursor = document.createElement("p");
    body.appendChild(file.cursor);
    file.cursor.innerText = file.name + " contient :";
                                
    file.text().then(function(value) {
      file.cursor.innerText += " " + value;
    });
    
    使用:

    但是,此解决方案不保证任何特定订单。每当解析文件的承诺(文件读取完成)时,只有该文件的内容才能添加到div中

    如果您绝对需要一个特定的内容附加顺序,那么也有许多可能的解决方案可以实现这一点,例如承诺链接

    但是我不确定这是否是一个要求,所以我不会给出比现在更长的答案:)

    在file.text()函数中,“file”是指最后声明的文件引用

    你的背景是C。在JS
    var
    s中,函数作用域和get。对于块范围变量,最好使用较新的关键字
    let
    const

    在file.text().then函数中,“this”指的是第一个调用方,即div本身

    这在JS中是臭名昭著的;特别是对于那些已经对它应该如何表现抱有期望的人来说。在JS
    中,此
    是上下文敏感的,取决于调用函数/方法的方式

    旁注:我看到你写了两次代码,看看。我使用它们将
    dataTransfer
    中可用的任何内容“规范化”为一系列
    文件

    var body=document.body;
    var cursor=document.createElement(“div”);
    cursor.innerText=“文件内容:\n”;
    // https://mdn.io/Generator
    函数*getFiles(数据传输){
    if(dataTransfer.items){
    // https://mdn.io/for...of
    for(让数据传输的项。项){
    如果(item.kind==“文件”){
    // https://mdn.io/yield
    yield item.getAsFile();
    }
    }
    }否则{
    // https://mdn.io/yield*
    yield*dataTransfer.files;
    }
    }
    cursor.ondragover=e=>e.preventDefault();
    cursor.ondrop=函数(e){
    e、 预防默认值();
    for(getFiles的常量文件(例如数据传输)){
    const fileCursor=document.createElement(“p”);
    fileCursor.innerText=file.name+“contient:”;
    body.appendChild(fileCursor);
    然后(text=>fileCursor.append(text));
    }
    };
    body.appendChild(游标)好的

    另一个答案指出,“var”的作用域是函数而不是块

    将“var”替换为“let”anywhere会使file.text()中的关键字“this”。然后回调不会指向任何内容,因为执行流

    无论如何,“let”使每个迭代的“file”独立

    因此,我使用了以下代码:

    <!DOCTYPE html>
    
    <html>
        <head>
            <title>Drag-Drop tests</title>
            <meta charset="UTF-8">
        </head>
        <body>
            <script>
                let body = document.body;
                
                let cursor = document.createElement("div");
                cursor.innerText = "Contenus des fichiers :\n";
                
                cursor.ondragover = e => e.preventDefault();
                cursor.ondrop = e => {
                    e.preventDefault();
                    
                    let fileLoad = file => {
                        file.cursor = document.createElement("p");
                        body.appendChild(file.cursor);
                        
                        file.cursor.innerText = file.name + " contient :";
                        file.text().then(value => file.cursor.innerText += " " + value);
                    }
                    
                    if(e.dataTransfer.items)
                        for(let item of e.dataTransfer.items)
                            if(item.kind === "file") fileLoad(item.getAsFile());
                    else
                        for(let file of e.dataTransfer.files)
                            fileLoad(file);
                };
                
                body.appendChild(cursor);
            </script>
        </body>
    </html>
    
    
    阻力降试验
    让body=document.body;
    让cursor=document.createElement(“div”);
    cursor.innerText=“文件内容:\n”;
    cursor.ondragover=e=>e.preventDefault();
    cursor.ondrop=e=>{
    e、 预防默认值();
    让fileLoad=file=>{
    file.cursor=document.createElement(“p”);
    appendChild(file.cursor);
    file.cursor.innerText=file.name+“contient:”;
    file.text().then(value=>file.cursor.innerText+=“”+value);
    }
    if(如数据传输项)
    用于(e.dataTransfer.items的let项)
    如果(item.kind==“file”)文件加载(item.getAsFile());
    其他的
    for(让文件为e.dataTransfer.files)
    文件加载(文件);
    };
    body.appendChild(游标);
    
    最后,我并不真正关心代码优化(对于行代码的数量)

    我将用一些C代码生成它。

    您的标题中提到了“this”关键字。也许我还没有喝足够的咖啡,但是我没有看到你在代码中的任何地方使用
    这个
    。相反,我看到您使用的是
    文件
    ,这绝对不是
    这个
    。最初的代码使用的是“this”,但是看,我提到了file.cursor.innerText+=by this.cursor.innerTex
    <!DOCTYPE html>
    
    <html>
        <head>
            <title>Drag-Drop tests</title>
            <meta charset="UTF-8">
        </head>
        <body>
            <script>
                let body = document.body;
                
                let cursor = document.createElement("div");
                cursor.innerText = "Contenus des fichiers :\n";
                
                cursor.ondragover = e => e.preventDefault();
                cursor.ondrop = e => {
                    e.preventDefault();
                    
                    let fileLoad = file => {
                        file.cursor = document.createElement("p");
                        body.appendChild(file.cursor);
                        
                        file.cursor.innerText = file.name + " contient :";
                        file.text().then(value => file.cursor.innerText += " " + value);
                    }
                    
                    if(e.dataTransfer.items)
                        for(let item of e.dataTransfer.items)
                            if(item.kind === "file") fileLoad(item.getAsFile());
                    else
                        for(let file of e.dataTransfer.files)
                            fileLoad(file);
                };
                
                body.appendChild(cursor);
            </script>
        </body>
    </html>