In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-03 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
在ES5环境下立即执行函数的示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
立即执行函数常用于第三方库,它可以用来隔离变量作用域,很多第三方库都会存在大量的变量和函数,在ES5环境下为了避免变量污染,开发者想到的解决办法就是使用立即执行函数。
本文就跟大家分享下立即执行函数的相关知识点,欢迎各位感兴趣的开发者阅读本文。
概念介绍
立即调用的匿名函数又被称作立即调用的函数表达式(IIFE),它类似于函数声明,但由于被包含在括号中,所以会被解释为函数表达式。紧跟在第一组括号后面的第二组括号会立即调用前面的函数表达式,位于IIFE中的代码在其外部是无法访问的。
我们举个例子来说明下:
(function() { // 块级作用域 for (var i = 0; i < 5; i++) { console.log(i); } })(); console.log(i);
上述代码中当解析到console.log(i);时,会报错ReferenceError: i is not defined,这是因为它访问的变量是在IIFE内部定义的,在外部访问不到。
在es5以前,为了防止变量定义外泄,IIFE是个非常有效的方式,这样也不会导致闭包相关的内存问题,因为不存在对这个匿名函数的引用。因此,只要函数执行完毕,其作用域链就可以被销毁。
IIFE的全称为Immediately Invoked Function Expression,翻译过来就是立即调用函数表达式。
模拟块级作用域
使用IIFE可以模拟块级作用域,即在一个函数表达式内部声明变量,然后立即调用这个函数,这样位于函数体作用域的变量就像是在块级作用域中一样(如上述例子所示)。
在ES6以后,新增了块级作用域的概念,因此我们想实现同样的效果,就无需再使用IIFE了,我们用let来重写下上面的例子,代码如下所示:
for (let i = 0; i < 5; i++) { console.log(i); } console.log(i);
有关变量作用域的更多知识点请移步我的另一篇文章:深入理解作用域和闭包
块级作用域无法替代立即调用函数的表达式,当你的代码在不支持ES6+的浏览器上运行时,你不得不求助立即执行函数来模拟。
实现私有变量
IIFE可以返回一个函数引用,当这个函数在IIFE的词法范围外执行,也会创建一个闭包,使函数能够访问局部变量。
我们举个例子来说明下,如下所示:
const getOrderId = (function() { let count = 0; return function() { ++count; return `id_${count}`; }; })(); console.log(getOrderId()); console.log(getOrderId()); console.log(getOrderId()); console.log(getOrderId());
上述代码中:
创建了一个自执行函数,其返回一个函数引用
自执行函数内部有一个变量count,它就是一个私有变量,外部无法访问
最后,返回一个函数引用,形成闭包结构,对count自增后与_id进行拼接并返回
在IIFE之外无法访问函数内部的count变量,除了从IIFE中返回的函数,别处无法读写该变量,这样就能创建真正的私有状态变量。
变量重命名
在平常开发中可能遇到两个不同的库,他们暴露的全局变量名却是相同的,例如:正在使用Jquery,另一个库也指定了一个名为$的全局变量。
为了解决命名冲突问题,可以将一段代码封装在一个IIFE中,将一个全局变量(比如Jquery)作为参数传入IIFE,在函数内部,就可以以一个任意的参数名(比如 $)来访问该参数值,我们举个例子来说明下,如下所示:
window.$ = function somethingElse() { // 其他代码 }; (function($) { // 其他代码 })(jQuery);
不管在全局作用域有什么值指定给,在IIFE中,这些值都会被屏蔽,`参数一直指向Jquery方法。
捕获全局对象
JavaScript代码在不同环境执行时,所使用的全局对象是不同的,当代码在浏览器环境运行时,全局对象是window,但是在node环境下,全局对象则是global。
在写通用js代码时,就可以利用IIFE将其包装起来,例如:
(function(global) { // 其他代码 })(this);
包装之后,在IIFE内部使用global时在浏览器环境下其值就是window,node环境下其值就是global。
IIFE的两种写法
立即执行函数有两种写法:
(function(){})() 匿名函数包裹在一个括号运算符中,后面再跟一个小括号
(function(){}()) 匿名函数后面跟一个小括号,然后整个包裹在一个括号运算符中
上述两种写法是等价的,要想立即执行函数做到立即执行,要注意两点:
函数体后面要有小括号
函数体必须是函数表达式而不能是函数声明
函数的声明方式
在讲它们两者之间的区别之前,我们先来了解下js函数的两种声明方式:表达式和声明式。
函数的声明式写法为:function test(){},这种写法会导致函数提升,所有通过function关键字声明的变量都会被解释器优先编译,不管声明在什么位置都可以调用它,但是它本身并不会被执行。
test(); // 测试 function test() { console.log("测试"); } test(); // 测试
函数的表达式写法为:var test = function(){},这种写法不会导致函数提升,必须先声明后调用,不然就会报错。
test(); // 报错:TypeError: test is not a function var test = function() { console.log("测试"); };二者的区别
现在,我们回到正题,函数表达式加上()可以被直接调用,但是把整个声明式函数用()包起来的话,则会被编译器认为是函数表达式,从而可以用()来直接调用,如(function test(){})()。
如果将括号加在声明式函数后面如function test(){},运行之后会报错,因为不符合js的语法,想让其通过浏览器的语法检查,就必须添加符号,比如:()、+、!等,如下所示:
function test(){ console.log("测试"); }(); // 报错 SyntaxError: Unexpected token ')' +function test() { console.log("测试"); }(); // 正常执行 -function test() { console.log("测试"); }(); // 正常执行 !function test() { console.log("测试"); }(); // 正常执行 ~function test() { console.log("测试"); }(); // 正常执行 void function test() { console.log("测试"); }(); // 正常执行 new function test() { console.log("测试"); }(); // 正常执行
立即执行函数一般也写成匿名函数,使用function关键字声明一个函数,但未给函数命名,通过这种方式声明的函数就是匿名函数,例如function(){}。
匿名函数不能单独使用,否则会js语法报错,需要用()包起来,当我们需要给匿名函数传值时,写在其后面的括号即可,例如:
(function(val) { console.log(val); }("我是匿名函数的参数"));
讲解到此处时,我们会发现,上述代码的写法正好是立即执行函数的第二种写法??,我们知道函数体后面跟着小括号,这个函数就会立即执行。
我们知道自执行函数是需要用()将其包裹起来的,前面我们讲到用()包裹起来的代码,编译器会认定它为函数表达式,因此可以在其后面加个()立即调用这个函数。同时也可以从这个括号来为匿名函数传参,代码如下所示:
(function(val) { console.log(val); })("我是自执行匿名函数");
我们发现上述代码的写法正好是立即执行函数的第一种写法??
关于在ES5环境下立即执行函数的示例分析问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.