在节点js中使用闭包

时间:2012-08-22 11:20:32

标签: javascript node.js closures

使用以下方法有什么不同?

第一种方法:

for(var i = 0; i < 10; i++) {
    (function(e){
        setTimeout(function() {
            console.log(e); 
        }, 1000);
    })(i);
}

for(var i = 0; i < 10; i++) {
    createTimeoutFunction(i);
}

第二种方法:

function createTimeoutFunction(e){ 
    setTimeout(function() {
        console.log(e); 
    }, 1000);
}

for(var i = 0; i < 10; i++) {
    createTimeoutFunction(i);
}

我是节点js和使用闭包的新手。虽然两种方法都返回相同的输出,但第二种方法运行时出错。我不明白为什么我们需要像第一种方法一样使用两个循环。我们不能像第二种方法一样执行吗?

2 个答案:

答案 0 :(得分:1)

删除第一个方法中的第二个for,因为除非您希望循环运行两次,否则它是多余的,因为第一个方法中已经发生了所有事情。第二个循环失败,因为createTimeoutFunction永远不会在第一个循环的范围之外定义,而不是第二个循环。

除此之外,它们都会产生相同的结果,唯一的区别在于第二种方法createTimeoutFunction是可重用的。

另请参阅:How do JavaScript closures work?

答案 1 :(得分:0)

无论您使用何种环境或解释器,javascript中的闭包都是一样的。

闭包提供了一组特定的变量作用域,在该作用域中执行该组代码。你的闭包可以(显然)访问自身内部定义的任何内容,以及任何封闭闭包中定义的任何对象。

你编码的问题是,在第一个例子createTimeoutFunction没有在任何地方定义 - 当你调用它时它会失败。在那个例子中:

(function(e){
    setTimeout(function() {
        console.log(e); 
    }, 1000);
})(i);

在此闭包中定义的函数是匿名函数。它没有name属性,无法引用。

第二个版本定义了一个全局变量createTimeoutFunction,然后可以在页面上的任何闭包中访问它,因为它是全局对象的一部分。 (好吧,我假设你因为你没有表明这个代码被其他任何东西包围了。)