function与感叹号

前言


相信大家都看到过在很多js代码中函数前面会有一个感叹号,这是什么意思呢?请往下看

!function(){alert('我最帅!')}()		// true

如上所示,这行代码在控制台输出,会执行alert语句,并返回true,这是为什么呢?

这是一个匿名函数自调,但是它输出了,并且返回了true,首先,解释下为什么返回true,这个不难理解,匿名函数的返回值是undefined,感叹号是非的意思,前面加一个非变成!undefined,所以返回true,不过重点不在这,接着往下看

。。。

正文


function(){alert('无敌了')}()			// 语法错误

我们都知道,如上所示的这种写法是不对的

匿名函数自调一般我们都会采用下面两种写法:

(function(){alert('嗯,输出了')})();

(function(){alert('嗯,也输出了')}());

那为什么上面把括号换成了感叹号的写法也可以执行匿名函数呢?

又是什么好处使多数前端攻城狮对这种叹号的方式情有独钟? 是因为感叹号的一个字符比起括号的两个字符更节省空间吗?

节省空间显然是没有太大的说服力的,确实累死也节省不了多少内存啊,那又是为了什么呢?

首先我们来说一下为什么感叹号写法可以执行匿名函数

其实不管是括号还是感叹号的写法都是为了让 js 函数声明变成函数表达式

看下面代码的解析

function fn(){'我又来了'}()		// Unexpected token

上述代码报错是为什么呢

大家都知道,function(){}是函数声明,是一个完整的语句,js解释器在解释完这个语句后就结束了,结束后会再解析后面的(),而js语法中()里面是需要有表达式语句的,这里()里面什么都没有,所以js解析就会报语法错误,完整来说,就是前面的function fn(){'我又来了'}这句函数声明语句是没有错误的,报的错是()的错误,不信你可以控制台把这条语句分开输入试试

结果肯定是函数语句没错,错的是()

function(){'没错,又是我'}()		// Unexpected token

那这条代码为什么错误呢?如上

注意这条代码和上面那条是不一样的,这条代码函数没有名字,众所周知,函数只有在函数表达式中才可以匿名,所以这里的错误是因为函数没有名字,之后的()根本就不会执行

var fn = function(){alert(250)};
fn();

这样为什么会执行?如上

因为变量fn是函数表达式的引用,相当于调用了一个表达式

function fn(){alert('哈哈哈')};
fn();

这样又是为什么可以执行呢?如上

是因为fn是函数名,它指向了这个函数,在当前的作用域中当然可以调用了

(function(){alert(111)})();

这样为什么又可以执行呢?如上

是因为js语法中()中只能是表达式,所以上述代码强制让js解释器认为里面的函数是一个表达式,所以语句后面加上()就可以执行函数了

综上所述,想要实现调用一个函数,只需要把函数变成表达式调用就行了

那么怎样可以把函数变成表达式呢

当然,括号和文章开头的感叹号都是可以的

其实有很多种方法都可以把函数变成表达式

!function(){alert(1)}();			// true

+function(){alert(1)}();			// NAN

-function(){alert(1)}();			// NAN

~function(){alert(1)}();			// -1

new function(){alert(1)}();			// Object

delete function(){alert(1)}();	  	// true

void function(){alert(1)}();		// undefined

(function(){alert(1)})();			// undefined

如上所示,这些一元运算符和关键字都可以,括号当然也没问题,并且这些写法都是合法的,唯一不同的是返回值不同罢了,但是我们的宗旨是调用匿名函数,返回值一般情况下是不需要在意的

最后是关于性能了,这些写法中,除了new的方式最慢(可以理解,对象嘛!!!),括号和加减号的方式最快,其他都差不多,所以说这几种写法都是可行的,但是为什么那么多的人用感叹号不用速度快又标准的括号呢?

。。。

总结


个人认为前端攻城狮喜欢用感叹号自调用函数的原因有四:

  • one

    感叹号确实比()简单点

  • two

    感叹号的代码可读性较强

  • three

    个人习惯

  • four

    写代码不喜欢写分号的开发者在函数自调用时通常喜欢用感叹号

    因为感叹号可以让我们自调用函数时不写分号也不报错,它防止了代码在合并的时候发生错误

    不写分号的情况下用()的方式自调用函数会报错,虽然js解释器会自动补全分号

    为什么()写法会报错呢,这个问题又牵扯到了js代码风格了

    有兴趣的话请阅读我的下篇博客文章js代码风格

以上就是我这次的分享!

本文是我自己的看法,如有错误,还请指出,不喜勿喷!

如果对您有用,请点击关注给我鼓励!谢谢

原创,转载请注明出处!

投诉建议邮箱:[email protected]

本文GitHub源件请点击-https://github.com/isboyjc/web-knowledge/function与感叹号.md

本文参考文章:https://swordair.com/function-and-exclamation-mark/

猜你喜欢

转载自blog.csdn.net/qq_43430453/article/details/83117002
今日推荐