这个Javascript(function(){})语法是什么

这个Javascript(function(){})语法是什么,javascript,Javascript,Javascript中的这种语法到底是什么?我看到它经常被使用(或滥用): 我知道它创建了一个匿名函数,然后执行它。但是,我不明白为什么会这样。这不等于一种更具可读性的形式吗: function initSomething() {} initSomething(); 编辑: 感谢大家的精彩回复,帮助我理解Javascript中的一个习语 第二个示例中的函数不再是匿名的。。。它有一个名字,initSomething 第一种语法通常用于设置闭包。。。捕获变量x、y、z和不在其中的变量,这样它们

Javascript中的这种语法到底是什么?我看到它经常被使用(或滥用):

我知道它创建了一个匿名函数,然后执行它。但是,我不明白为什么会这样。这不等于一种更具可读性的形式吗:

 function initSomething() {}
 initSomething();
编辑:
感谢大家的精彩回复,帮助我理解Javascript中的一个习语

第二个示例中的函数不再是匿名的。。。它有一个名字,
initSomething


第一种语法通常用于设置闭包。。。捕获
变量x、y、z
和不在其中的变量,这样它们就不会与闭包外具有相同名称的任何其他变量冲突。

两种方法都可以,但第一种情况是匿名函数(它没有名称,所以可以避免冲突等等)。

基本上它是一个未命名的(匿名)函数加载后立即执行的函数


使用此方法的原因是为了尽可能远离全局范围,并将您的变量与其他任何可能在别处定义的变量隔离开来,您可以在函数中定义变量和其他函数,而不会对全局范围内的所有变量和函数发垃圾邮件。

这是一个自调用匿名函数

function(){}
是一个匿名函数文本

(function(){})(
调用该文本

因为这是一个调用自身的匿名函数,所以它是一个自调用的匿名函数

与第二种形式相比,第一种形式的优势在于,它为您提供了一种简单的方法来封装您不希望污染全局名称空间的代码

您也没有不必要地创建一个函数
initSomething
,它现在是全局名称空间的一部分,并且可能会破坏其他东西

如果您对更多信息感兴趣,也可以查看。

这是一个立即调用的函数表达式

摘自维基百科,因为它解释得很好

立即调用的函数表达式(或IIFE,发音为“iffy”)是一种JavaScript设计模式,它使用JavaScript的函数作用域生成词法作用域。立即调用的函数表达式可用于避免从块内提升变量,防止污染全局环境,同时允许公众访问方法,同时保留函数内定义的变量的隐私

有关更详细的说明,请参阅

我知道它创建了一个匿名函数,然后执行它。但是,我不明白为什么会这样。这不等于一种更具可读性的形式吗:

 function initSomething() {}
 initSomething();

这是不一样的,因为
initSomething
仍然可以被引用,因此不是匿名的。

在JavaScript中,函数创建新的作用域。在JavaScript的全部内容周围使用函数包装器将确保您永远不会污染全局范围

例如,如果您有一个底部带有一些JavaScript的HTML文件:

<script>
var test = 'hello';
alert(test);          //'hello'
alert(window.test);   //'hello'
</script>
请注意,与任何匿名函数一样,这只是一个普通的匿名函数。结束大括号后的参数集调用匿名函数。整个事件周围的参数告诉解释器它正在查看一个值或表达式,而不是函数声明。该值只是匿名函数运行时的结果。这使得匿名函数像一个简单的闭包一样工作,程序员可以有效地忽略它

此外,您可以对IIFE使用两种不同的语法:

(function() {}());
(function() {})();
使用其中任何一个都不太可能出现问题,但当代码中出现一些语法问题时,就会出现问题。在我看来,你最好还是坚持第一条,这一条读起来也更清晰

--

关于你的第二个问题:以下两个是等价的吗?

(function(){})();

嗯,嗯,有点。你也许可以用同样的方法来对待它们,因为在大多数情况下,它们的作用是一样的。也就是说,在您的程序中,您将使用其中任何一个获得相同的结果(在这两种情况下,您都定义了一个函数,然后调用它)

但是注意匿名函数和函数声明之间的区别很重要。您可以将匿名函数视为可执行文件,或者当您不想定义一个真正的命名函数时,您可以将其作为胶水传递。因为它们是匿名的,所以它们不存在于作用域链中,并且,例如,您不能向匿名函数对象添加属性并在以后使用它们,除非您首先将其分配给变量,在这种情况下,它不再是匿名的

声明一个函数是完全不同的。它创建了一个构造函数,您可以反复使用它来创建可以继承原始函数属性的新对象(使用
new
)。这对很多事情都很有用,特别是在使用像AngularJS这样的框架时

function Friend(likes_you) {
    //private property, only accessible to instances of this object
    this.likes_you = likes_you;
}

//add a function as a property of Friend's prototype -
//instances of the Friend constructor can call this function
Friend.prototype.greet = function(greeting) {
    if (this.likes_you) {
        alert(greeting);
    } else {
        alert("I don't like you");
    }
};

var you = new Friend(true);
you.greet('hello!');          //alerts 'hello!'

var guy = new Friend(false);  //can make as any Friend objects as we want
guy.greet('hello!');          //alerts "I don't like you"

当然,您不需要做任何类似的事情,但是了解JavaScript真正在做什么很好。这只是JS兔子洞的开始…

这是一个立即/自调用的函数表达式。
(function(){alert(“匿名函数!!!”)})(
),这与混淆无关。你问它是什么,然后说你已经知道了。你的问题到底是什么?你是否在问为什么人们使用它而不是命名函数?你似乎在你的岗位中间换挡了。谁说“一定是那样的”?没有。如果你想命名一个你再也不会使用的函数,那么就这样做。啊,相当于Python中的猴子补丁。美好的谢谢你的解释。所有其他答案都很好。但我特别喜欢这张照片中结构的对比。我觉得讽刺的一件事是,我看到的大多数使用这种自动可执行匿名函数的代码都是
(function() {}());
(function() {})();
(function(){})();
function initSomething() {}
initSomething();
function Friend(likes_you) {
    //private property, only accessible to instances of this object
    this.likes_you = likes_you;
}

//add a function as a property of Friend's prototype -
//instances of the Friend constructor can call this function
Friend.prototype.greet = function(greeting) {
    if (this.likes_you) {
        alert(greeting);
    } else {
        alert("I don't like you");
    }
};

var you = new Friend(true);
you.greet('hello!');          //alerts 'hello!'

var guy = new Friend(false);  //can make as any Friend objects as we want
guy.greet('hello!');          //alerts "I don't like you"