2015-07-22 67 views
0

我是一个javascript新手,试图围绕这段代码考虑一下。 我在这里得到了http://brackets.clementng.me/post/24150213014/example-of-a-javascript-closure-settimeout-inside这是一个立即调用的函数表达式吗?

我还是很难理解它。因为它涉及一些我不熟悉的模式。

// output 0-9, seperated by 1 sec delay. 
for (var i = 0; i < 10; i++) { 
    setTimeout(function(x) { 
     return function() { 
      console.log(x); 
     }; 
    }(i), 1000*i); 
} 

(i)在这段代码中的含义是什么?

function(x) { 
    return function() { 
     console.log(x); 
    }; 
}(i) 

我认为这是一个立即调用的函数表达式。 但没有为正确的语法是:

(function() { 
    // some code 
})(); 
+0

如果有人在这里感兴趣的是对相同代码的另一种解释。 http://stackoverflow.com/questions/12930272/javascript-closures-vs-anonymous-functions?rq=1 –

回答

2

也就是说,确实是一个IIFE。你引用的语法是一个0参数的IIFE;您询问的语法是1个参数的IIFE。它将在内部代码中将i分配给x。比较:

var print0 = function() { 
    console.log("Hello!"); 
}; 
print0(); 

是(隔离),相当于

(function() { 
    console.log("Hello!"); 
})(); 

这样的名字:您创建一个函数,然后立即调用它。

但是,如果你想要一个说法,没有什么变化:

var print1 = function(name) { 
    console.log("Hello, " + name); 
}; 
print1("George"); 

是(隔离),相当于

(function(name) { 
    console.log("Hello, " + name); 
})("George"); 

括号这里确保函数的定义将被视为一个表达而不是声明。还有其他的方法来确保,一个常见的一种是

!function() { 
    console.log("Hello!"); 
}(); 

(但我们有理由喜欢的括号内。)由于您使用它作为参数传递给setTimeout调用,它不可能是一个声明,所以这些黑客是没有必要的。它仍被称为“立即调用函数表达式”,因为您仍在构造函数表达式并立即调用它。

此处使用IIFE的原因是“捕获”变量i的值,而不是x的位置。没有关闭技巧,你会得到10个超时,全部输出10(当console.log解决时,由x表示的位置的值)。

+0

我明白了!感谢您的快速回复男士欣赏它 –

0

是的,和(i)是呼叫参数列表。详细解释请看here。在这种情况下,分组圆括号是毫不含糊的,因为它是对函数调用的一个参数,因此也是表达式。

术语IIFE不仅指这种模式的陈述形式,其中parenthesis would be necessary

+0

该链接是非常有帮助的,谢谢! :) –

0

在你的直接调用函数的示例中,可选项是可选项。

(function() { 
    // some code 
})(); 

可以重新写为

function() { 
    // some code 
}(); 

在例子中函数的调用i成为函数定义的x

function(x) { // x = 1 
    return function() { 
     console.log(x); // x = 1 
    }; 
}(1) 
相关问题