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。在JSvar
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>