2024年JavaScript进阶(二十三):立即执行函数(匿名函数)( ( ) (1),阿里前端面试题

文末

我一直觉得技术面试不是考试,考前背背题,发给你一张考卷,答完交卷等通知。

首先,技术面试是一个 认识自己 的过程,知道自己和外面世界的差距。

更重要的是,技术面试是一个双向了解的过程,要让对方发现你的闪光点,同时也要 试图去找到对方的闪光点,因为他以后可能就是你的同事或者领导,所以,面试官问你有什么问题的时候,不要说没有了,要去试图了解他的工作内容、了解这个团队的氛围。

前端面试题汇总

JavaScript

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

性能

linux

前端资料汇总

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. 因为undefinedwindow的属性,声明为局部变量之后,在函数中如果再有变量与undefined作比较的话,程序就可以不用搜索undefinedwindow,可以提高程序性能。

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

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

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

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

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

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

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

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

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

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

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


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

在这里插入图片描述

立即执行函数一般也写成匿名函数,匿名函数写法为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,正常执行

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

  1. 不必为函数命名,避免污染全局变量。
  2. 立即执行函数内部形成一个独立的作用域,可以封装一些外部无法读取的私有变量,这个作用域里面的变量,外面访问不到,这样就可以避免变量污染。
  3. 封装变量。
  4. 闭包和私有数据。
2.1 立即执行函数使用的场景
  1. 代码逻辑在页面加载完成之后,不得不执行一些设置工作,比如时间处理器,创建对象等等。
  2. 所有的这些工作只需要执行一次,比如只需要显示一个时间。
  3. 但是这些代码也需要一些临时的变量,但是初始化过程结束之后,就再也不会被用到,如果将这些变量作为全局变量,不是一个好的设计,可以用立即执行函数——去将所有的代码包裹在它的局部作用域中,不会让任何变量泄露成全局变量,如下代码:
当前时间:<span id="today"></span>
<script>
	(function(){
		var todaydom=document.getElementById("today");
		var days=["星期日","星期一","星期二","星期三","星期四","星期五","星期六"1; 
		var today=new Date( );
		var year=today.getFullYear(); 
		var month=today.getMonth()+1; 
		var date=today.getDate(); 
		var day=today.getDay();
		var msg=year+"年"+month+"月"+date+"日"+days [day]; 
		todaydom.innerHTML=msg;
	})()
</script>

比如上面的代码,如果没有被包裹在立即执行函数中,那么临时变量todaydom,days,today,year,month,date,day,msg都将成为全局变量(初始化代码遗留的产物)。用立即执行函数之后,这些变量都不会在全局变量中存在,以后也不会其他地方使用,有效的避免了污染全局变量。

总结👇🏻:立即执行函数会形成一个单独的作用域,可以封装一些临时变量或者局部变量,避免污染全局变量。

像其他函数一样,立即执行函数也可以有返回值。除了可以返回基本类型值以外,立即执行函数也能返回任何类型的值,比如对象,函数。

var result = (function(){
	var res = 2+2;
	return function( ) { return res;
	})()
console.log(result());//4

上例中立即执行函数的返回值被赋值给了一个变量result,这个函数简单的返回了res的值,这个值事先被计算并被存储在立即执行行数的闭包中。

2.2 立即执行函数有哪些作用?
2.2.1 改变变量的作用域(创建一个独立的作用域)
<body>
    <ul id="list">
#### 后话

-------------------------------------------------------------

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

对于面试,说几句个人观点。



面试,说到底是一种考试。正如我们一直批判应试教育脱离教育的本质,为了面试学习技术也脱离了技术的初心。但考试对于人才选拔的有效性是毋庸置疑的,几千年来一直如此。除非你有实力向公司证明你足够优秀,否则,还是得乖乖准备面试。这也并不妨碍你在通过面试之后按自己的方式学习。
其实在面试准备阶段,个人的收获是很大的,我也认为这是一种不错的学习方式。首先,面试问题大部分基础而且深入,这些是平时工作的基础。就好像我们之前一直不明白学习语文的意义,但它的意义就在每天的谈话间。

所谓面试造火箭,工作拧螺丝。面试往往有更高的要求,也迫使我们更专心更深入地去学习一些知识,也何尝不是一种好事。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值