当前位置: 首页 > 科技观察

是时候停止使用JavaScriptIIFE了!

时间:2023-03-18 18:51:57 科技观察

本文转载自公众号《读芯》(ID:AI_Discovery)在JavaScript语言中,IIFE全称是ImmediatelyInvokedFunctionExpression,即定义后立即执行的函数。为什么我说停止在代码中编写IIFE?这篇文章会给你答案。Block-Scoped变量可以定义在JavaScript中作为ES6的标准发布,你可以使用let和const来声明block-scoped变量和常量。它还引入了独立的块,可以将变量和常量隔离到自己的块中,不能在外面使用。比如你可以这样写:{letx=1;}那么x对外是不可用的。这比下面的代码更简洁:(()=>{letx=1;})();现在几乎所有的浏览器都支持ES6,不再使用IIFE将变量与外部隔离。隔离变量的另一种方法是使用模块,它也得到广泛支持。只要不导出,其他模块就无法使用。不再需要闭包闭包是一个返回另一个函数的函数。返回的函数可以运行它外面的代码,但是里面的代码是由闭包函数运行的。例如,它可能产生:constid=(()=>{letcount=0;return()=>{++count;return`id_${count}`;};})();当块和模块都隔离数据时,上述功能变得更加复杂和不必要。可以将所有函数放入它们自己的模块中,这样您就不必担心暴露数据,但这也有副作用。由于它不是纯函数,因此很难对其进行测试。返回函数的函数在可以避免嵌套的情况下引入了嵌套,因此它比不返回函数的函数更容易混淆。使用模块代替是最好的方法。使用模块写:letcount=0;exportconstid=()=>{++this.count;return`id_${count}`}上面代码中有相同的count语句,导出id函数为其他模块使用。这就像一个IIFE,隐藏计数并公开我们想要的函数,但嵌套更少,无需定义另一个函数来运行它。别名变量同理,写入如下内容:window.$=functionfoo(){//...};(function($){//...})(jQuery);你可以使用模块来编写它,为什么只编写一个IIFE来为变量创建别名?使用模块,您可以导入具有不同名称的东西。您可以像这样为变量创建别名:import{$asjQuery}from"jquery";const$=()=>{};另外,不要向窗口对象添加新属性,这会影响全局范围。捕获全局对象使用globalThis,你不用担心全局对象在不同作用域的名称,它正在成为一个标准。除了使用IIFE来捕获全局对象,您可以在该部分的顶层编写如下内容:(function(global){//...})(this);或者甚至在“globalThis”之前,写这样的东西来设置全局对象不太难:constglobalObj=self||window||global;或者如果你想更精确,你可以这样写:typeofglobal!=='undefined'){returnglobal;}thrownewError('unabletolocateglobalobject');};无需通过IIFE添加额外的函数调用和引入嵌套。最佳压缩应用JavaScript模块,而不必使用IIFE隔离代码,这会适当地压缩文件。Netpack、Browse、Parcel、Rollup等(Webpack、Browserify、Parcel、Rollup等程序)都能正确处理模块,为什么不使用这些程序来创建更简洁的代码。用代码编写IIFE已经过时了,它还会添加额外的函数定义和嵌套。在2020年,选择将您的代码与模块和块分开!