Ej.*_*Ej. 406 javascript closures iife self-executing-function
在javascript中,你想什么时候使用它:
(function(){
//Bunch of code...
})();
Run Code Online (Sandbox Code Playgroud)
对此:
//Bunch of code...
Run Code Online (Sandbox Code Playgroud)
Ken*_*ing 385
一切都与变量范围有关.默认情况下,在自执行函数中声明的变量仅可用于自执行函数中的代码.这允许编写代码而不用考虑如何在其他javascript代码块中命名变量.
例如:
(function(){
var foo = 3;
alert(foo);
})();
alert(foo);
Run Code Online (Sandbox Code Playgroud)
这将首先警告"3",然后在下一个警报上抛出错误,因为未定义foo.
小智 82
简单化.看起来很正常,几乎让人感到安慰:
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
Run Code Online (Sandbox Code Playgroud)
然而.如果我在页面中包含一个非常方便的javascript库,将高级字符转换为基本级别表示,该怎么办?
等等......什么?
我的意思是.如果有人输入带有某种重音的角色(例如法语或西班牙语),但我只想要'英语'字符?Az在我的节目中?嗯......西班牙语'n~'和法语'e /'字符(我为这些字符分别使用了两个字符,但你可以在表达重音的字符中进行精神跳跃),这些字符可以被翻译成为'n'和'e'的基本字符.
所以有一个好人已经写了一个全面的字符转换器,我可以包括在我的网站...我包括它.
一个问题:它有一个名为'name'的函数,与我的函数相同.
这就是所谓的碰撞.我们在相同的范围内声明了两个具有相同名称的函数.我们想避免这种情况.
所以我们需要以某种方式确定代码的范围.
在javascript中扩展代码范围的唯一方法是将其包装在函数中:
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
Run Code Online (Sandbox Code Playgroud)
这可能会解决我们的问题.现在所有东西都是封闭的,只能从我们的开始和结束括号中访问.
我们在函数中有一个函数......这看起来很奇怪,但完全合法.
只有一个问题.我们的代码不起作用.我们的userName变量永远不会回显到控制台!
我们可以通过在现有代码块之后添加对函数的调用来解决此问题...
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
main();
Run Code Online (Sandbox Code Playgroud)
或之前!
main();
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
Run Code Online (Sandbox Code Playgroud)
次要问题:"主要"这个名称还没有被使用的可能性有多大?......非常非常苗条.
我们需要更多的范围.以及一些自动执行main()函数的方法.
现在我们来到自动执行功能(或自动执行,自运行,等等).
((){})();
语法像罪一样尴尬.但是,它的工作原理.
当您将函数定义包装在括号中并包含参数列表(另一组或括号!)时,它将充当函数调用.
所以让我们再看一下我们的代码,使用一些自动执行的语法:
(function main() {
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
)();
Run Code Online (Sandbox Code Playgroud)
因此,在您阅读的大多数教程中,您现在将使用"匿名自执行"或类似的术语进行轰炸.
经过多年的专业开发,我强烈建议您为调试目的命名您编写的每个函数.
当出现问题时(它会出现问题),您将在浏览器中检查回溯.它总是更容易缩小你的代码的问题时,在堆栈跟踪中的条目有名字!
非常啰嗦,我希望它有所帮助!
M A*_*onu 33
自调用(也称为自动调用)是函数在定义时立即执行的.这是一个核心模式,是许多其他JavaScript开发模式的基础.
它是一个伟大的粉丝:)因为:
极大 - (为什么你应该说它好?)
更多这里.
Chr*_*oph 19
命名空间.JavaScript的范围是功能级别的.
Dav*_*ith 12
我不敢相信没有提到暗示全局的答案.
该(function(){})()构造不能防止隐含的全局变量,这对我来说是更大的问题,请参阅http://yuiblog.com/blog/2006/06/01/global-domination/
基本上,功能块确保您定义的所有相关"全局变量"仅限于您的程序,它不会保护您不会定义隐式全局变量.JSHint等可以提供有关如何防御此行为的建议.
更简洁的var App = {}语法提供了类似的保护级别,并且可以在"公共"页面上包含在功能块中.(有关使用此构造的库的真实示例,请参阅Ember.js或SproutCore)
就private属性来说,除非你要创建公共框架或库,否则它们会被高估,但如果你需要实现它们,Douglas Crockford有一些好主意.
我已经阅读了所有答案,在此遗漏了一些非常重要的内容,我会接吻。有两个主要原因,为什么我需要自执行匿名函数,或者最好说“ 立即调用函数表达式(IIFE) ”:
第一个已经很好地解释了。对于第二个,请研究以下示例:
var MyClosureObject = (function (){
var MyName = 'Michael Jackson RIP';
return {
getMyName: function () { return MyName;},
setMyName: function (name) { MyName = name}
}
}());
Run Code Online (Sandbox Code Playgroud)
注意1:我们没有分配功能MyClosureObject,更何况是调用该功能的结果。请注意()最后一行。
注意2:您还需要进一步了解Java语言中的函数,即内部函数可以访问内部定义的函数的参数和变量。
让我们尝试一些实验:
我可以MyName使用了getMyName,它可以工作:
console.log(MyClosureObject.getMyName());
// Michael Jackson RIP
Run Code Online (Sandbox Code Playgroud)
以下巧妙的方法不起作用:
console.log(MyClosureObject.MyName);
// undefined
Run Code Online (Sandbox Code Playgroud)
但是我可以设置另一个名称并获得预期的结果:
MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName());
// George Michael RIP
Run Code Online (Sandbox Code Playgroud)
编辑:在上面的示例MyClosureObject中设计为不带new前缀使用,因此按照惯例,不应将其大写。
是否有参数和"一堆代码"返回一个函数?
var a = function(x) { return function() { document.write(x); } }(something);
Run Code Online (Sandbox Code Playgroud)
关闭.something分配给的函数使用的值的值a.something可以有一些不同的值(for循环)和每次a有一个新的功能.
这是一个自我调用匿名函数如何有用的可靠示例.
for( var i = 0; i < 10; i++ ) {
setTimeout(function(){
console.log(i)
})
}
Run Code Online (Sandbox Code Playgroud)
输出: 10, 10, 10, 10, 10...
for( var i = 0; i < 10; i++ ) {
(function(num){
setTimeout(function(){
console.log(num)
})
})(i)
}
Run Code Online (Sandbox Code Playgroud)
输出: 0, 1, 2, 3, 4...
| 归档时间: |
|
| 查看次数: |
124196 次 |
| 最近记录: |