最后
喜欢的话别忘了关注、点赞哦~
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
函数()
这样的语句我们都知道是让一个函数运行,而括号中的值表示传值,比如:
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属性值。
在前面加分号可以有以下几种用途:
- 防止多文件集成成一个文件后,高压缩出现语法错误。
- 这是一个匿名函数,一般
js
库都采用这种自执行的匿名函数来保护内部变量(function(){})()
- 因为
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引擎会认为后面跟的是表达式,而不是一个函数定义语句,所以就避免了错误,这就叫做"立即调用的函数表达式"
立即执行函数一般也写成匿名函数,匿名函数写法为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,正常执行
立即执行函数主要有以下特点:
- 不必为函数命名,避免污染全局变量。
- 立即执行函数内部形成一个独立的作用域,可以封装一些外部无法读取的私有变量,这个作用域里面的变量,外面访问不到,这样就可以避免变量污染。
- 封装变量。
- 闭包和私有数据。
2.1 立即执行函数使用的场景
- 代码逻辑在页面加载完成之后,不得不执行一些设置工作,比如时间处理器,创建对象等等。
web浏览器中的javascript
- 客户端javascript
- 在html里嵌入javascript
- javascript程序的执行
- 兼容性和互用性
- 可访问性
- 安全性
- 客户端框架
- 开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
window对象
-
计时器
-
浏览器定位和导航
-
浏览历史
-
浏览器和屏幕信息
-
对话框
-
错误处理
-
作为window对象属性的文档元素