What is the purpose of passing arguments to anonymous functions in this manner?
Possible Duplicate:
How do JavaScript closures work?
我在玩谷歌闭包编译器,输入随机代码看看它会做什么。
它重写了我的一个函数,使其看起来像这样:
1
| (function(msg) { console.log(msg); })("Hello World!");??????? |
其中,"Hello World"似乎是作为msg传递给它前面的匿名函数的参数。我看了一会儿,觉得在jquery插件中我看到了类似的东西,类似于:
1 2 3
| (function( $ ) {
...
})(jQuery); |
在与$的冲突范围内,这对我来说更有意义。但是,将参数传递到这样一个匿名函数的主要原因或目的是什么?为什么不简单地将参数定义为函数中的变量呢?编写这样的函数有什么性能或灵活性优势吗?
- 对于那个特定的代码,没有真正的原因。你只需要做一个console.log("hello");。但通常需要创建一些局部变量,这些局部变量只能由内部创建和导出的某些函数访问。
- 我很好奇看到您的原始代码导致了这种形式。我敢打赌,如果您启用了高级的_优化,它将完全摆脱这个函数。
- @用户1689607的功能有点不同,而且更长。我把事情简单化了。比这个具体的例子更想知道这个概念
- 哦,如果问题主要是函数参数和变量,那肯定不是性能问题。更可能的是,它可以避免使用var 字符以减小文件大小。
- 如果您像这样传递全局变量,您将能够在缩小时更改它的名称。缩小不会重命名全局变量,因此,如果出现100次,拥有类似"myGlobalVariable.property"的内容将占用大量空间。如果你把它传递给你的anon函数并在里面命名它,minifier会把它的名字改为,例如a,减少你的应用程序的总大小。
还有一个显著的差异与范围有关。以下代码:
1
| (function(msg) { console.log(msg); })("Hello World!");??????? |
在某些情况下,命名空间污染比这更严重:
1 2
| var msg ="Hello World!";
console.log(msg); |
因为第二个代码在不再需要变量之后会留下变量,但可能会干扰代码的其他部分。
当您在任何其他函数之外执行上述代码时,这一点尤其重要:在这种情况下,msg变量将作为全局变量在页面的任何位置都可用。
- 但是,将第二个示例包装在一个匿名函数中会有什么不同呢?变量最后还是会消失。
- 我觉得他更像这样的意思:jfiddle.net/cv5jp
- @凯文布,你的小提琴和我发布的功能有什么区别?
- @???????l??:我认为这个论点仍然有效。编译器刚刚选择了(function(msg){ console.log(msg); })("sth"),而不是!function(msg){ console.log(msg); }("sth")、(function(){ var msg="sth"; console.log(msg); })()等。这是一个非常简单的例子,我不希望它背后有魔力,它只是其中一种方法。
- @塔贝克,我想你是对的,认为我期待一点魔法。更重要的是,我想知道那里是否有魔法,这种方法是否对我所做的任何事情都有好处
- @???????l??:您使用的确切代码是什么?这可能会影响结果,我看到Google闭包编译器不会将(function(){ var msg="sth"; console.log(msg); })();转换为(function(msg){ console.log(msg); })("sth");。
- 我把代码放在一把小提琴里:jsfiddle.net/coffee_coder/nkzve,我又一次乱弄乱弄,想看看会发生什么,然后缩短了我的问题,不认为上下文是非常重要的,尽管我想我最终错了。
- @???????l?好的,现在很明显了。它是关于在全局命名空间中保存不必要的变量:首先定义b()函数,然后使用它一次,它将保留在全局命名空间中。因此,自然的方法是将函数转换成任意的、自称的函数。在正文中添加新的参数可能会导致代码出现问题,编译并没有那么具有攻击性。
这有点取决于上下文。有些情况下,编译器根本不会尝试内联任何函数(例如,如果作用域函数包含"eval")。如果这是一个全局范围内的,并且您正在高级模式下运行,那么仅仅是在编译器停止尝试内联函数之后出现了内联机会(或者内联代码中有一个bug,它错过了这个机会)。如果在高级模式下通过编译器运行示例输出,则会得到:
1
| console.log("Hello World!"); |
基本上,最好将代码包装在下面:(function(){/*code*/}());,以防止var与其他人的var发生冲突。
我认为闭包编译器最主要的功能是保存5个字符:var 和=。