JS:a之间有什么区别?闭包和()闭? [英] JS: What's the difference between a ! closure and () closure?

查看:171
本文介绍了JS:a之间有什么区别?闭包和()闭?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

所以我回去看一些自己的代码以及一些其他的javascript代码,我意识到,一开始我开始写javascript库时,我使用的闭包看起来像这样:

So I was going back and looking over some of my own code as well as some other javascript code and I realized that a while back when I started writing javascript libraries I was using closures that looked something like this:

(function( window, document, undefined ) {
    // code
})( window, document );

但是我看到一些bootstrap代码,我改成了这种语法:

But then I saw some bootstrap code and I changed to this syntax:

! function (window, document, undefined) {
    // code
}(window, document);

现在,如果我没有错(请纠正我, !前面的匿名函数只是导致它被视为'()'然后返回(无处不在)一个布尔值,该函数返回的值是否未定义,null或空。

Now, if I'm not wrong (and please correct me if I am), placing the '!' in front of my anonymous function just causes it to be treated as '()' then returns (into nowhere?) a boolean value of whether the value returned by the function was not undefined, null, or empty.

我想知道的是,在'()()'之间使用'!()'语法真的有区别吗?有某些浏览器会抱怨吗?

What I'm wondering is, is there really a difference between using the '!()' syntax over '()()'? Are there certain browsers that will complain?

任何想法都感谢,谢谢! XD

Any thoughts are appreciated, thanks! XD

推荐答案

你要问的是自调用函数,也称为IIFE(立即调用函数表达式)。这是一个与闭包不同的东西。虽然它确实创建了一个闭包(事实上,所有的函数在javascript创建闭包,而不仅仅是IIFE)。

What you're asking about is self-calling functions, otherwise known as IIFE (immediately invoked function expression). Which is a different thing from a closure. Although it does create a closure (indeed, all functions in javascript create closures, not just IIFE).

这是可以理解的,你可能会混淆这两个问题,通常在解释闭包的上下文中引入。但要知道,他们是不同的东西。闭包是私有的,共享的类似全局变量。 IIFE是根据定义立即调用的函数。

It's understandable that you may confuse the two issues though, since IIFE are usually introduced in the context of explaining closures. But be aware that they are different things. Closures are private, shared "global-like" variables. IIFE are functions that gets called immediately upon their definitions.

现在,IIFE如何工作?线索在名字。这是FEIIFE - 函数表达式。

Now, how does IIFE work? The clue is in the name. It's the "FE" IIFE - function expression.

在javascript中,你知道,有两种方法来创建函数 - 使用函数声明:

In javascript, as you know, there are two ways of creating functions - using function declarations:

function foo () {}

并使用函数表达式:

foo = function () {}

函数表达式只是在表达式的上下文*中声明的函数。什么是javascript中的表达式?

A function expression is simply a function declared in the context* of an expression. What are expressions in javascript? Simply any statement that evaluates something.

传统上,人们将表达式识别为:

Traditionally, people recognize expressions as:




  1. anything on the right side of the = sign

 a = /* expression */


  • 大括号中的任何内容

  • anything in braces

    (/* expression */)
    


  • 因此,传统上这些是声明函数表达式的两种标准方式:

    So traditionally those are the two "standard" ways for declaring function expressions:

    foo = function(){}
    

    (function(){})
    

    第二个语法使得很容易执行由表达式返回的函数对象。但是,真的,一个表达式是任何地方的数学(或逻辑,这是数学无论如何)。因此,向函数声明添加运算符也将其转换为表达式。以下工作原理是因为它们是一元运算符(意​​思是,它们是合法的,在左侧没有任何东西):

    And the second syntax makes it easy to then execute the function object returned by the expression. But, really, an expression is anywhere js does math (or logic, which is math anyway). So adding an operator to a function declaration also turns it into an expression. The following works because they are unary operators (meaning, they are legal without anything on the left hand side):

    !function(){}()
    
    +function(){}()
    
    -function(){}()  // I especially like this one because it
                     // looks like a command line switch
    
    typeof function(){}()
    

    但是你也可以使用二进制运算符,如果你使用一些丢弃值或变量。以下也工作:

    But you can also use binary operators if you use some throw-away value or variable with it. The following also work:

    x=function(){}()
    0==function(){}()
    1*function(){}()
    2/function(){}()
    

    Heck,你甚至可以滥用三元运算符:

    Heck, you can even abuse the ternary operator:

    0?0:function(){}() // valid and works!
    

    没有什么神奇的。这不是一个特定的语法烘焙到javascript。就像(function(){}())不是IIFE的特定语法。只是当在表达式中声明时,函数返回自身作为可以立即调用的对象。

    There's nothing magical about it. It's not a specific syntax baked into javascript. Just like (function(){}()) is not a specific syntax for IIFE. It's just that when declared in an expression, functions return themselves as objects which can be called immediately.

    但是我建议不要使用上面的非标准形式虽然。出于同样的原因,你问这个问题 - 大多数javascript程序员不习惯看到它们,它可能会导致混乱。我自己没有意识到,你可以这样做,直到你问这个问题。仍然,要知道什么时候需要编写minifiers,代码生成器等内容是非常有用的。

    But I'd advise against using any of the non-standard forms above though. For the same reason you asked this question - most javascript programmers are not used to seeing them and it can cause confusion. I myself didn't realize that you can do this until you asked the question. Still, it's a useful thing to know for when you need to write things like minifiers, code generators etc.

    * I 'm使用上下文在它的传统定义这里不是规范中定义的上下文的javascript特定含义。

    * I'm using "context" in it's traditional definition here not the javascript specific meaning of "context" as defined in the spec.

    这篇关于JS:a之间有什么区别?闭包和()闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆