Javascript 函数前的感叹号有什么作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3755606/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:01:28  来源:igfitidea点击:

What does the exclamation mark do before the function?

javascriptfunction

提问by Sebastian Otto

!function () {}();

回答by Neil

JavaScript syntax 101. Here is a function declaration:

JavaScript 语法 101。这是一个函数声明

function foo() {}

Note that there's no semicolon: this is just a function declaration. You would need an invocation, foo(), to actually run the function.

请注意,没有分号:这只是一个函数声明。您需要调用 ,foo()才能实际运行该函数。

Now, when we add the seemingly innocuous exclamation mark: !function foo() {}it turns it into an expression. It is now a function expression.

现在,当我们添加看似无害的感叹号时:!function foo() {}它变成了一个表达式。它现在是一个函数表达式

The !alone doesn't invoke the function, of course, but we can now put ()at the end: !function foo() {}()which has higher precedence than !and instantly calls the function.

!单独不会调用函数,当然,但我们现在可以把()结尾:!function foo() {}()它的优先级高于!并立即调用函数。

So what the author is doing is saving a byte per function expression; a more readable way of writing it would be this:

所以作者所做的是为每个函数表达式保存一个字节;一种更具可读性的写作方式是:

(function(){})();

Lastly, !makes the expression return true. This is because by default all IIFE return undefined, which leaves us with !undefinedwhich is true. Not particularly useful.

最后,!使表达式返回真。这是因为默认情况下所有 IIFE 都返回undefined,这给我们留下了!undefinedwhich is true。不是特别有用。

回答by Michael Burr

The function:

功能:

function () {}

returns nothing (or undefined).

不返回任何内容(或未定义)。

Sometimes we want to call a function right as we create it. You might be tempted to try this:

有时我们想在创建函数时立即调用它。你可能会想试试这个:

function () {}()

but it results in a SyntaxError.

但它会导致SyntaxError.

Using the !operator before the function causes it to be treated as an expression, so we can call it:

!在函数之前使用运算符会导致它被视为表达式,因此我们可以调用它:

!function () {}()

This will also return the boolean opposite of the return value of the function, in this case true, because !undefinedis true. If you want the actual return value to be the result of the call, then try doing it this way:

这也将返回与函数返回值相反的布尔值,在本例中true,因为!undefinedis true。如果您希望实际返回值是调用的结果,请尝试这样做:

(function () {})()

回答by dmi3y

There is a good point for using !for function invocation marked on airbnb JavaScript guide

!airbnb JavaScript 指南中标记的用于函数调用有一个好处

Generally idea for using this technique on separate files (aka modules) which later get concatenated. The caveat here is that files supposed to be concatenated by tools which put the new file at the new line (which is anyway common behavior for most of concat tools). In that case, using !will help to avoid error in if previously concatenated module missed trailing semicolon, and yet that will give the flexibility to put them in any order with no worry.

在单独的文件(又名模块)上使用这种技术的一般想法,这些文件后来被连接起来。这里需要注意的是,文件应该由将新文件放在新行的工具连接(这对于大多数连接工具来说都是常见的行为)。在这种情况下,!如果先前连接的模块错过了尾随分号,使用将有助于避免错误,但这将提供灵活地将它们按任何顺序排列而无需担心。

!function abc(){}();
!function bca(){}();

Will work the same as

将与

!function abc(){}();
(function bca(){})();

but saves one character and arbitrary looks better.

但保存一个字符,任意看起来更好。

And by the way any of +,-,~,voidoperators have the same effect, in terms of invoking the function, for sure if you have to use something to return from that function they would act differently.

顺便说一下,任何+, -, ~,void运算符在调用函数方面都具有相同的效果,当然,如果您必须使用某些东西从该函数返回,它们的行为会有所不同。

abcval = !function abc(){return true;}() // abcval equals false
bcaval = +function bca(){return true;}() // bcaval equals 1
zyxval = -function zyx(){return true;}() // zyxval equals -1
xyzval = ~function xyz(){return true;}() // your guess?

but if you using IIFE patterns for one file one module code separation and using concat tool for optimization (which makes one line one file job), then construction

但是,如果您使用 IIFE 模式进行一文件一模块代码分离并使用 concat 工具进行优化(这使得一行一个文件工作),那么构造

!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()

Will do safe code execution, same as a very first code sample.

将执行安全的代码,与第一个代码示例相同。

This one will throw error cause JavaScript ASI will not be able to do its work.

这将引发错误,导致 JavaScript ASI 将无法完成其工作。

!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()

One note regarding unary operators, they would do similar work, but only in case, they used not in the first module. So they are not so safe if you do not have total control over the concatenation order.

关于一元运算符的一个注意事项,它们会做类似的工作,但只是以防万一,它们不在第一个模块中使用。因此,如果您不能完全控制串联顺序,它们就不那么安全了。

This works:

这有效:

!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()

This not:

这不是:

^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()

回答by gilly3

It returns whether the statement can evaluate to false. eg:

它返回语句是否可以评估为假。例如:

!false      // true
!true       // false
!isValid()  // is not valid

You can use it twice to coerce a value to boolean:

您可以使用它两次将值强制为布尔值:

!!1    // true
!!0    // false

So, to more directly answer your question:

所以,更直接地回答你的问题:

var myVar = !function(){ return false; }();  // myVar contains true

Edit:It has the side effect of changing the function declaration to a function expression. E.g. the following code is not valid because it is interpreted as a function declaration that is missing the required identifier(or function name):

编辑:它具有将函数声明更改为函数表达式的副作用。例如,以下代码无效,因为它被解释为缺少所需标识符(或函数名称)的函数声明:

function () { return false; }();  // syntax error

回答by Varatharaj

Its just to save a byte of data when we do javascript minification.

它只是为了在我们进行 javascript 缩小时保存一个字节的数据。

consider the below anonymous function

考虑下面的匿名函数

function (){}

To make the above as self invoking function we will generally change the above code as

为了使以上成为自调用函数,我们通常将上面的代码更改为

(function (){}())

Now we added two extra characters (,)apart from adding ()at the end of the function which necessary to call the function. In the process of minification we generally focus to reduce the file size. So we can also write the above function as

现在,(,)除了()在调用函数所需的函数末尾添加之外,我们还添加了两个额外的字符。在缩小的过程中,我们通常专注于减小文件大小。所以我们也可以把上面的函数写成

!function (){}()

Still both are self invoking functions and we save a byte as well. Instead of 2 characters (,)we just used one character !

两者仍然是自调用函数,我们也保存了一个字节。(,)我们只使用了一个字符而不是 2个字符!

回答by SoEzPz

!is a logical NOToperator, it's a boolean operator that will invert something to its opposite.

是一个逻辑NOT运算符,它是一个布尔运算符,可以将某些东西反转为相反的东西。

Although you can bypass the parentheses of the invoked function by using the BANG(!) before the function, it will still invert the return, which might not be what you wanted. As in the case of an IEFE, it would return undefined, which when inverted becomes the boolean true.

尽管您可以通过在函数前使用BANG(!)绕过被调用函数的括号,但它仍然会反转返回,这可能不是您想要的。与 IEFE 的情况一样,它将返回undefined,当反转时变为布尔值 true。

Instead, use the closing parenthesis and the BANG (!) if needed.

相反,如果需要,请使用右括号和 BANG ( !)。

// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what's happening.

(function(){ return false; }());
=> false

!(function(){ return false; }());
=> true

!!(function(){ return false; }());
=> false

!!!(function(){ return false; }());
=> true

Other Operators that work...

其他有效的运算符...

+(function(){ return false; }());
=> 0

-(function(){ return false; }());
=> -0

~(function(){ return false; }());
=> -1

Combined Operators...

组合运算符...

+!(function(){ return false; }());
=> 1

-!(function(){ return false; }());
=> -1

!+(function(){ return false; }());
=> true

!-(function(){ return false; }());
=> true

~!(function(){ return false; }());
=> -2

~!!(function(){ return false; }());
=> -1

+~(function(){ return false; }());
+> -1

回答by oozzal

Exclamation mark makes any function always return a boolean.
The final value is the negation of the value returned by the function.

感叹号使任何函数总是返回一个布尔值。
最终值是函数返回值的否定。

!function bool() { return false; }() // true
!function bool() { return true; }() // false

Omitting !in the above examples would be a SyntaxError.

!在上面的例子中省略将是SyntaxError

function bool() { return true; }() // SyntaxError

However, a better way to achieve this would be:

但是,实现这一目标的更好方法是:

(function bool() { return true; })() // true

回答by kamal

Its another way of writing IIFE (immediately-invoked function expression).

它是另一种编写 IIFE(立即调用的函数表达式)的方式。

Its other way of writing -

它的另一种写作方式 -

(function( args ) {})()

same as

与...一样

!function ( args ) {}();

回答by antzshrek

!will negate (opposite) whatever you're expecting as a result, i.e if you have

!将否定(相反)你所期望的结果,即如果你有

var boy = true;
undefined
boy
true
!boy
false

when you call boy, your result will be true, but the moment you add the !when calling boy, i.e !boy, your result will be false. Which in other words you mean NotBoy, but this time it's basically a boolean result, either trueor false.

当你打电话时boy,你的结果将是true,但是当你添加!时调用的那一刻boy,即!boy你的结果将是false. 其中换句话说,你的意思是NotBoy,但这次它基本上是一个布尔结果,无论是truefalse

That's the same thing that happens to the !function () {}();expression, running only function () {}();will flag you an error, but add !right in front of your function () {}();expression, makes it the opposite of the function () {}();which should return you true. Example can be seen below:

这与!function () {}();表达式发生的情况相同,运行只会function () {}();标记您一个错误,但!在您的function () {}();表达式前面添加,使其与function () {}();返回 you的相反true。示例如下:

function () {}();
SyntaxError: function statement requires a name
!function () {}();
true