Javascript:如何在回调函数中访问局部变量
Javascript: How to access local variable in callback function?
我有一个强大的形式来解析请求。然后,与此请求一起上传的文件。在强大的中,如果有文件,您可以收听事件。
var form = new formidable.IncomingForm({
uploadDir: __dirname + '/temp',
keepExtensions: true
});
这是我将聆听活动的地方
form.on('file', function(name, file){
var file = file;
fs.readFile(file.path, readFileCallback);
});
function readFileCallback(err, contents){
console.log(file);
if (err) throw err;
....
}
我的第一个代码是一系列回调函数,它有点难以阅读和维护,所以我切换了这种方法,我将声明函数然后将其调用为回调,而不是像这样:
form.on('file', function(name, file){
fs.readFile(file.path, function(err, contents){
console.log(file);
if (err) throw err;
....
});
});
使用这种方法,我可以访问file
的外部变量。我想知道两者在访问外部变量方面有什么区别。提前谢谢。
这是一个范围问题。代码可以访问函数中声明的变量、包含函数(如果有(、包含函数(如果有(等,然后访问全局变量。
在第一个示例中,readFileCallback
是在form.on
回调之外声明的,因此它无法访问form.on
回调中的内容。
在第二个示例中,函数位于 form.on
回调内,因此它确实可以访问其中的内容。
请注意,在第二个示例中,理论上每次调用回调时都会创建一个新函数。没关系,JavaScript 引擎在创建函数方面非常快(即使创建了单独的函数对象,好的引擎也会重用代码(。
通常,您希望在最外层的位置创建函数,在该位置可以访问所需的所有内容。所以在你的例子中,这将在form.on
内部,但在readFile
回调之外。这正是您的第二个示例所在。但是如果你愿意,你可以像你的第一个例子一样使用命名函数,只需把它放在form.on
的回调中:
form.on('file', function(name, file){
fs.readFile(file.path, readFileCallback);
function readFileCallback(err, contents){
console.log(file);
if (err) throw err;
....
}
});
让我们举一个例子,其中所有内容都有一个简单的名称,并遵循两个调用:
function outer(outerArg) {
function middle(middleArg) {
function inner(innerArg) {
console.log("innerArg = " + innerArg);
console.log("middleArg = " + middleArg);
console.log("outerArg = " + outerArg);
}
inner(middleArg.toLowerCase());
}
middle(outerArg.toUpperCase());
}
outer
包含middle
,其中包含inner
,outer
调用middle
(以及middle
调用inner
(。一个电话:
outer("Test1");
-
outer
得到参数"Test1"
- 它用
"TEST1"
调用middle
- 它用
"test1"
调用inner
inner
输出:innerArg = test1中间参数 = 测试1外部Arg = 测试1
到目前为止,很简单,但它比这更令人兴奋:如果middle
返回一个调用inner
的函数,而不是立即调用它,并且outer
返回返回middle
的返回值怎么办?
function outer(outerArg) {
function middle(middleArg) {
function inner(innerArg) {
console.log("innerArg = " + innerArg);
console.log("middleArg = " + middleArg);
console.log("outerArg = " + outerArg);
}
function caller() { // ***
inner(middleArg.toLowerCase()); // ***
} // ***
return caller; // ***
}
return middle(outerArg.toUpperCase()); // ***
}
现在,调用outer
根本没有任何输出:
var f = outer("Test2");
但是调用返回middle
函数(caller
(会:
f();
输出:
innerArg = test2中间参数 = 测试2外部Arg = 测试2
outer
后争论仍然存在,middle
回归!但更有趣的是:
var f1 = outer("Test3");
var f2 = outer("Test4");
f2(); // Note -- calling the second one first
f1();
输出:
innerArg = test4中间参数 = 测试4外部Arg = 测试4innerArg = test3中间参数 = 测试3外部Arg = 测试3
所以这意味着,在对outer
的两次调用完成后,仍然存在两个outerArg
,以及两个middleArgs
。如何?
它们存在于附加到函数的对象上:
- 调用
outer
会创建一个执行上下文(一个对象(,除其他外(并省略了很多细节(保存了该调用outer
的参数和局部变量。我们称之为"外部语境"。它还具有对包含它的执行上下文的引用(在我们的代码中为全局上下文(。通常,当函子返回时,该对象会被清理... - 。但是
outer
创建了一个函数,middle
.创建函数时,当前执行上下文将附加到该函数。这就是它如何在外部上下文中访问变量等。 -
outer
调用middle
,创建一个内部执行上下文,middle
创建另外两个函数(inner
和caller
(,每个函数都附加了内部上下文。 然后middle
返回caller
,因此caller
在对middle
的调用完成后存在。由于caller
具有对内部执行上下文的引用,因此该上下文将继续存在(就像任何其他对象一样(,即使middle
已返回。由于该上下文有对inner
的引用,inner
也继续存在。 -
outer
返回middle
的返回值(即caller
(,因此这意味着当outer
返回时caller
仍然存在,这意味着它引用的内部上下文仍然存在,这意味着inner
仍然存在,外部上下文仍然存在,因为内部上下文具有对它的引用。
。这就是f1
和f2
在outer
返回后访问这些参数的方式:当您运行它们时,它们会在附加到它们的上下文中查找值。
- javascript函数访问ios本机功能
- 从嵌套函数访问函数属性
- 将typescript函数访问到angular中
- 全局变量只能由第一个函数访问
- Javascript从匿名函数访问外部对象属性
- UI网格:如何从自定义函数访问MODEL_COL_FIELD
- 在jQuery中,我如何从$.ajax回调函数访问$(this)
- 如何在JavaScript中停止从特定函数访问某些函数和变量
- 从jQuery.ech()函数访问外部作用域
- Angular2/Typescript:从链接可观察函数访问实例变量
- 局部变量仍可通过函数访问
- 从Kendo中的columns.filterable.cell.template函数访问列字段名
- 可以't从JS函数访问combodate
- 如何在javascript中将变量从一个函数访问到另一个函数
- jQuery从PHP函数访问Ajax响应
- 如何从json函数访问javascript中的基类变量
- 在OPP JS中,您可以从构造函数访问原型函数内部声明的方法
- Javascript 使用函数访问其他类
- 从 JavaScript 中的私有函数访问公共函数
- 为什么我无法从茉莉花中的 javascript 函数访问全局变量