我读了一些关于闭包的帖子,到处都能看到这一点,但没有明确的解释它是如何工作的-每次我只是被告知使用它.:

// Create a new anonymous function, to use as a wrapper
(function(){
    // The variable that would, normally, be global
    var msg = "Thanks for visiting!";

    // Binding a new function to a global object
    window.onunload = function(){
        // Which uses the 'hidden' variable
        alert( msg );
    };
// Close off the anonymous function and execute it
})();

好的,我知道我们将创建新的匿名函数,然后执行它.因此,在这之后,这个简单的代码应该可以工作(它确实可以):

(function (msg){alert(msg)})('SO');

我的问题是这里发生了什么样的魔法?我想,当我写的时候:

(function (msg){alert(msg)})

然后将创建一个新的未命名函数,如函数""(Msg).

但为什么这不管用呢?

(function (msg){alert(msg)});
('SO');

为什么要排在同一条线上呢?

你能给我指出一些帖子或给我一个解释吗?

推荐答案

在函数定义后删除分号.

(function (msg){alert(msg)})
('SO');

上面的方法应该有效.

演示页面:https://jsfiddle.net/e7ooeq6m/

我在这篇文章中讨论过这种模式:

jQuery and $ questions

EDIT:

如果你看ECMA script specification,有3种方法可以定义一个函数.(第98页,第13节功能定义)

1.使用函数构造函数

var sum = new Function('a','b', 'return a + b;');
alert(sum(10, 20)); //alerts 30

2.使用函数声明.

function sum(a, b)
{
    return a + b;
}

alert(sum(10, 10)); //Alerts 20;

3.函数表达式

var sum = function(a, b) { return a + b; }

alert(sum(5, 5)); // alerts 10

所以你可能会问,声明和表达有什么区别?

来自ECMA脚本规范:

功能声明:

函数表达式:

如果您注意到,函数表达式的"标识符"是optional.如果不提供标识符,则创建一个匿名函数.这并不意味着不能指定标识符.

这意味着以下内容是有效的.

var sum = function mySum(a, b) { return a + b; }

需要注意的重要一点是,"mySum"只能在mySum函数体内部使用,不能在外部使用.请参见以下示例:

var test1 = function test2() { alert(typeof test2); }

alert(typeof(test2)); //alerts 'undefined', surprise! 

test1(); //alerts 'function' because test2 is a function.

Live Demo

将此与

 function test1() { alert(typeof test1) };

 alert(typeof test1); //alerts 'function'

 test1(); //alerts 'function'

有了这些知识,让我们试着分析你的代码.

当你有这样的代码,

    function(msg) { alert(msg); }

您创建了一个函数表达式.可以通过将函数表达式包装在括号中来执行它.

    (function(msg) { alert(msg); })('SO'); //alerts SO.

Javascript相关问答推荐

功能和普通对象之间的原型污染

如何制作删除按钮以从列表中删除该项目所属的项目?

为什么在react js中没有调用加载器函数?

不渲染具有HTML参数的React元素

在贝塞尔曲线的直线上找不到交叉点:(使用@Pomax的bezier.js)

调用removeEvents不起作用

防止用户在selectizeInput中取消 Select 选项

如何修复我的js构建表每当我添加一个额外的列作为它的第一列?

查找最长的子序列-无法重置数组

我的角模板订阅后不刷新'

如何在ASP.NET JavaScript中使用Google Charts API仅对绘制为负方向的条形图移动堆叠条形图标签位置

类构造函数不能在没有用With Router包装的情况下调用

React.Development.js和未捕获的ReferenceError:未定义useState

try 使用PM2在AWS ubuntu服务器上运行 node 进程时出错

获取';无法解决导入和导入";slick-carousel/slick/slick-theme.css";';错误

<;img>;标记无法呈现图像

在GraphQL解析器中修改上下文值

如何使用puppeteer操作所有选项

在Press Reaction本机和EXPO av上播放单个文件

如何向内部有文本输入字段的HTML表添加行?