2024年最全JavaScript进阶(二十三):立即执行函数(匿名函数)( ( ) (3),2024年最新面经解析

最后

在面试前我花了三个月时间刷了很多大厂面试题,最近做了一个整理并分类,主要内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。

包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

  • HTML5新特性,语义化

  • 浏览器的标准模式和怪异模式

  • xhtml和html的区别

  • 使用data-的好处

  • meta标签

  • canvas

  • HTML废弃的标签

  • IE6 bug,和一些定位写法

  • css js放置位置和原因

  • 什么是渐进式渲染

  • html模板语言

  • meta viewport原理


拆解以上语句如下:


1. `var tensquared = xx;` 这是赋值语句;
2. `function (x){ return x*x; }` 这是一个匿名函数;所谓的匿名函数是指它没有自己的名字,既不是`function name(){};`拥有一个函数名,也不是`var name = function(){};`将函数赋给一个变量地址用于日后的调用;


为什么会有这样的函数呢,因为有时候只是临时地一次性地使用一个函数,用过了这个函数也就再没用了,那么这个时候就用到了匿名函数(当然,并不一定说只有一次性的才会用到匿名函数,还有其它的情况,不一一举例了。)


3. `函数()` 这样的语句我们都知道是让一个函数运行,而括号中的值表示传值,比如:



function name(arg){ alert(arg); };
name(‘yes’);


那么,程序执行到`name();`这个语句的时候,会将’yes’这个字符串传递到函数name中去,并执行name函数;


上面的函数我们再来理解一下:  
 `function(x){return x*x;}`是一个函数,然后直接在它后面加上个括号,是不是表示直接运行这个匿名函数呢:



function(x) {return x*x;}(10)


这一步等价于下面的方法:



function name(x){return x*x;}
name(10);


再加上赋值:



var tensquared = function(x) {return x*x;}(10);


是不是与下面这一系列的代码起到的效果一样呢:



function name(x){return x*x}
var tensquared = name(x);


应用下面这种实现方式之后,`name()`函数以后还可以通过`name(值);`这样的方式再一次去调用,因为有函数名,就可以用这个方法调用到它;


而`var tensquared=function(x) {return x*x;}(10)`这样的方式,是当时就执行了,然后将执行的结果赋值给了它前面的变量tensquared,以后想再调用`return x*x`所在的函数,却没办法了,因为它没名字,运行后就找不到了;


最后说说外面的括号,这个括号其实是可有可无的,而且这个括号的用法与人们常用的另一种用法有所偏差,因为括号括在最外围,已经失去了它的意义,其实应该是这样的:



var tensquared=(function(x) {return x*x;})(10);


只将匿名函数本体给括了起来,因为有时候`function`函数体很长,那么加一个括号告诉程序,这是一个完整的整体,其实这一步就算这样用,也是可有可无的。


再说说这种用法的意义:


像这种用法,大多数时候就是用来获取到一个值,而这个值却是需要一系列的计算后才能得到的,而这个计算的过程,只需用到一次,不需要再用第二次了,这时候,这种语句结构就有用了。


例如获取用户在使用浏览器类型:



var browser = function(){
if(是IE浏览器) return ‘IE’;
else if(是chrome浏览器) return ‘CH’;
else if(是Firefox浏览器) return ‘FF’;
}();


后面如果再想知道用户的浏览器名称,只要调用`browser`这个变量,看看返回的字符串就可以了。


### 二、立即执行函数


阅读源码过程中,经常看到一些大牛的JS源码会在`function`前面加语句结束符`;`



;(function(arg){
//some js code in here
})(param);


`;function($,undefined)` 是什么用处 ?


其实它就是创建了一个匿名函数`function(arg){ //some js code in here }`,然后再执行且只执行该函数一次,param为实参。


最前面加`;`是为了防止其他语句的影响,因此语句结束符`;`可有可无。如:



new
(function() {
this.prop = 4;
}) ().prop;


上面将匿名函数用作构造函数,然后实例化并取出prop属性值。


在前面加分号可以有以下几种用途:


1. 防止多文件集成成一个文件后,高压缩出现语法错误。
2. 这是一个匿名函数,一般`js`库都采用这种**自执行的匿名函数**来保护内部变量 `(function(){})()`
3. 因为`undefined`是`window`的属性,声明为局部变量之后,在函数中如果再有变量与`undefined`作比较的话,程序就可以不用搜索`undefined`到`window`,可以提高程序性能。



> 
> 立即执行函数👉🏻:声明一个函数,并马上调用这个匿名函数就叫做**立即执行函数**;即立即执行函数是定义函数以后立即执行该函数。
> 
> 
> 


定义好函数之后,立即调用该函数,这时不能在函数的定义后面直接加圆括号,会产生语法错误。



//这是错误的
function fn(){}()


这是因为:`function` 这个关键字,既可以当做语句,也可以当做表达式  
 比如:



//语句
function fn() {};
//表达式
var fn = function (){};


为了避免解析上的歧义,JS引擎规定,如果`function`出现在行首,一律解析成语句。


因此JS引擎看到行首是`function`关键字以后,认为这一段都是函数定义,不应该以原括号结尾,所以就报错了。


解决方法就是不要让`function`出现在行首,让JS引擎将其理解为一个表达式。最简单的处理就是将其放在一个圆括号里,比如下边:



//立即执行函数的两种写法

//第一种:用括号把整个函数定义和调用包裹起来
(function(){
//function body
}())

//第二种:用括号把函数定义包裹起来,后面再加括号
(function (){
//function body
})()


上边的两种写法,就是立即执行函数的两种写法,都是以圆括号开头,JS引擎会认为后面跟的是表达式,而不是一个函数定义语句,所以就避免了错误,这就叫做"**立即调用的函数表达式**"


![在这里插入图片描述](https://img-blog.csdnimg.cn/554f66d0d90a4008b13b0f29a205a513.png)


立即执行函数一般也写成匿名函数,匿名函数写法为`function(){/…/}`,所谓匿名函数,就是使用`function`关键字声明一个函数,但未给函数命名,倘若需要传值,直接将参数写到括号内即可。


将它赋予一个变量则创建函数表达式,赋予一个事件则成为事件处理程序等。但是需要注意的是匿名函数不能单独使用,否则会`js`语法报错,至少要用`()`包裹起来。


了解了立即函数的原理,就可以再扩展出其他的写法:



(function foo(){console.log(“Hello World!”)}())//用括号把整个表达式包起来,正常执行
(function foo(){console.log(“Hello World!”)})()//用括号把函数包起来,正常执行
!function foo(){console.log(“Hello World!”)}()//使用!,求反,这里只想通过语法检查。
+function foo(){console.log(“Hello World!”)}()//使用+,正常执行
-function foo(){console.log(“Hello World!”)}()//使用-,正常执行
~function foo(){console.log(“Hello World!”)}()//使用~,正常执行
void function foo(){console.log(“Hello World!”)}()//使用void,正常执行
new function foo(){console.log(“Hello World!”)}()//使用new,正常执行


立即执行函数主要有以下特点:




### 最后

![](https://img-blog.csdnimg.cn/img_convert/7abd04cbad4b4595f20a1484df02238b.webp?x-oss-process=image/format,png)

![](https://img-blog.csdnimg.cn/img_convert/73029d312bedba188db8062bd8084cf4.webp?x-oss-process=image/format,png)

**资料过多,篇幅有限**

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

>自古成功在尝试。不尝试永远都不会成功。勇敢的尝试是成功的一半。





立即执行函数主要有以下特点:




### 最后

[外链图片转存中...(img-4XGSr5Ch-1715646281918)]

[外链图片转存中...(img-yxbojWWK-1715646281919)]

**资料过多,篇幅有限**

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

>自古成功在尝试。不尝试永远都不会成功。勇敢的尝试是成功的一半。



  • 28
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值