Node.js-内联裸函数调用和命名函数调用之间的区别

Node.js-内联裸函数调用和命名函数调用之间的区别,node.js,Node.js,我正在学习node.js和learnyounode。我在处理异步时遇到问题。问题描述如下: 我对C/C++/C#/python/等有很多经验。。。所以我习惯于在某个特定的问题上组织我的代码。我在这个练习中遇到了一个我无法解释的问题。如果下面的代码在第一个for循环中以getHttp作为函数调用运行,那么程序将在索引上出现引用错误(关于cbk_handleStream中的第27行..)。我对“闭包”做了一些搜索和阅读,我认为我正在解决这个问题 一两个小时后,我决定使用更多的'node.js'格式(

我正在学习node.js和learnyounode。我在处理异步时遇到问题。问题描述如下:

我对C/C++/C#/python/等有很多经验。。。所以我习惯于在某个特定的问题上组织我的代码。我在这个练习中遇到了一个我无法解释的问题。如果下面的代码在第一个for循环中以getHttp作为函数调用运行,那么程序将在索引上出现引用错误(关于cbk_handleStream中的第27行..)。我对“闭包”做了一些搜索和阅读,我认为我正在解决这个问题

一两个小时后,我决定使用更多的'node.js'格式(getHttp2)重写。。。我几乎100%确信这在语法上是等价的——但它不会在索引变量上出错。事实上,这正是我认为“结束”应该采取的方式

我已经看了一遍又一遍,我不明白为什么它应该(或者为什么它会被设计)功能不同。命名回调函数可以工作。我甚至尝试了bind,发现了同样的问题

有什么想法或解释吗?提前谢谢你的帮助

干杯!
var concat=require('concat-stream');
var http=require('http');
//获取传递到cmd行的URL列表
var url=process.argv.slice(2);
var数据=[];
var计数=0;

for(var i=0;i快速查看-
索引
getHttp2
中的一个参数,在
getHttp2
中使用。但在
getHttp
中,它是一个局部变量,在
cbk\u handleStream
中超出范围

更精确的解释:这是您的代码:

function a() {
  console.log(i);
}

function b(i) {
  a();
}

b(1);
// prints: undefined.
这定义了一个函数
a
,它查找全局变量
i
并打印它。
b
定义了一个局部变量
i
,它只
b
看到;因此
a
中的
i
是未定义的

function b(i) {
  function a() {
    console.log(i);
  }
  a();
}

b(2);
// prints: 2.
另一方面,这个代码是不同的。
b
中的
i
是相同的,是一个局部变量。不同的是
a
是在
b
中定义的,并且关闭
b
中范围内的所有变量。因此,
a
将携带对
i
的引用。当您阅读
i
a
中,您不再访问全局变量,而是访问
b
中的局部变量,该
a
关闭(因此,关闭)

如果您从外部调用
a
b
,只要在
b
中定义了
a
,此功能甚至可以工作:

function b(i) {
  function a() {
    console.log(i);
  }
  return a;
}
var c = b(3);
c();
// prints: 3.
事实上,既然你说你会说Python,情况完全一样:

def a():
    print(i)
def b(i):
    a()
b(1)
# NameError: global name 'i' is not defined

def b(i):
    def a():
        print(i)
    a()
b(2)
# prints: 2.

def b(i):
    def a():
        print(i)
    return a
c = b(3)
c()
# prints: 3.

在这两种情况下,错误的原因是相同的:在第一个示例中没有闭包,而在第二个和第三个示例中,
i
上有闭包。

很有趣。因此,尽管您可以在代码的其他地方定义回调函数,然后引用它(就像我在getHttp()中所做的那样)流路径。它最终会在语法上有所不同,因为作用域是如何与嵌套函数一起工作的,因为如果函数在其他地方定义,则会丢失“闭包”。好吧,它有点正交,但完全可以理解,这种差异纯粹是一个作用域问题。