当前位置:  开发笔记 > 编程语言 > 正文

感叹号在功能之前做了什么?

如何解决《感叹号在功能之前做了什么?》经验,为你挑选了7个好方法。

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

function foo() {}

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

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

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

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

(function(){})();

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



1> Neil..:

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

function foo() {}

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

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

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

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

(function(){})();

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


+1.这真的是最好的答案,遗憾的是,几乎没有投票.显然,`!`返回boolean,我们都知道,但你要做的很重要的是它还将函数声明语句转换为函数表达式,以便可以立即调用该函数而不将其包含在括号中.不明显,而且显然是编码人员的意图.
另一个好处是!导致分号插入,因此不能将此版本与不以;结尾的文件错误地连接起来.如果你有()表单,它会认为它是前一个文件中定义的函数调用.给我的同事戴帽子的小费.
+1这是实际解决你想要做什么的唯一答案,以及为什么人们认为它的使用超过了对返回结果的否定似乎是值得的.一元运算符!(也是〜, - 和+)从函数声明中消除歧义,并允许end()中的parens就地调用函数.这通常用于在编写模块化代码时为变量创建局部范围/命名空间.
@Carnix`var foo =`打破语句/表达歧义,你可以简单地写`var foo = function(bar){}("baz");`等.
这看起来很难看......长篇大论不会太长,不能选择感叹号.这种方式可以为开发人员节省一小部分时间,并为其他人节省数小时.
这通常通过缩小/ uglification脚本来完成,其中每个字节都是重要的.
@PabloEzequielLeoneSignetti:它与代码的长度无关,无论在这个答案中提出的虚假声明如何.它是关于使用未被覆盖的运算符用于多种目的,可以根据其周围的代码以不同的方式进行解释.`!`是前缀一元运算符,只会被解释为.我怀疑任何有能力的开发人员需要"花时间理解"这一点.
对于从未见过它的人来说,"更具可读性"的版本不再具有可读性,也不易理解,这就是为什么SO上有这么多问题,询问`(function(){})()`的含义.
一个缺点是!强制返回值。有时这很重要,有时则无关紧要-但是,如果您碰巧需要测试该函数的返回值,并且“未定义”是有可能的,那么最好不要使用!约定,而是使用({})(),因为它可以返回未定义的值。考虑:var foo =!function(bar){}(“ bat”); console.log(“ foo:”,foo); // => true句:var foo =(function(bar){})(“ bat“); console.log(” foo:“,foo); // =>未定义
这不是101的一部分

2> Michael Burr..:

功能:

function () {}

什么都不返回(或未定义).

有时我们想在创建函数时调用函数.你可能想尝试这个:

function () {}()

但它导致了一个SyntaxError.

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

!function () {}()

这也将返回与函数返回值相反的布尔值,在这种情况下true,因为!undefinedtrue.如果您希望实际返回值是调用的结果,那么尝试这样做:

(function () {})()


谁能够需要这个?
您的第二个代码示例不是有效的JavaScript.`!`的目的是将函数声明转换为函数表达式,这就是全部.
这是唯一的**答案,解释了问题中的案例,勇敢!
@Andrey bootstrap twitter在所有javascript(jQuery)插件文件中都使用了这个.添加此评论以防其他人也可能有相同的问题.
d3.js也使用`!function`语法

3> dmi3y..:

使用airbnb JavaScript指南!上标记的函数调用是很有意义的

通常在单独的文件(也称为模块)上使用此技术的想法,后来得到连接.这里需要注意的是,文件应该通过将新文件放在新行的工具连接起来(这对于大多数concat工具来说无论如何都是常见的行为).在这种情况下,使用!将有助于避免错误,如果以前连接的模块错过了尾随分号,但这将提供灵活性,以任何顺序放置它们,不用担心.

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

将工作相同

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

但保存两个字符和任意看起来更好.

顺便说一句任何的+,-,~,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?

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

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

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

这个会抛出错误导致JavaScript ASI无法完成其工作.

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

关于一元运算符的一个注释,它们会做类似的工作,但仅限于它们不在第一个模块中使用的情况.因此,如果您无法完全控制连接顺序,那么它们就不那么安全了.

这有效:

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

这不是:

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


实际上,那些其他符号没有相同的效果.是的,它们允许您按照描述调用函数,但它们不相同.考虑:var foo =!function(bar){console.debug(bar); }("蝙蝠"); 无论你放在前面的哪个符号,你都会在你的控制台中得到"蝙蝠".现在,添加console.debug("foo:",foo); - 根据您使用的符号,您会得到非常不同的结果.!强制一个并不总是令人满意的返回值.为了清晰和准确,我更喜欢({})()语法.

4> gilly3..:

它返回语句是否可以计算为false.例如:

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

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

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

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

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

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

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


为了清楚读者可能想要使用具有立即调用函数的赋值,您的示例代码`var myVar =!function(){return false; }()`可以省略`!`,如`var myVar = function(){return false; }()`并且函数将正确执行,返回值将保持不变.

5> oozzal..:

感叹号使任何函数始终返回布尔值.最终值是函数返回的值的否定.

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

!在上面的例子中省略了一个SyntaxError.

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

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

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



6> SoEzPz..:

!是一个逻辑NOT运算符,它是一个布尔运算符,它会反转某些东西.

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

相反,如果需要,使用右括号和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

其他有效的运营商......

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

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

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

联合运营商......

+!(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



7> 小智..:

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

考虑下面的匿名函数

function (){}

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

(function (){}())

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

!function (){}()

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

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有