JS 中的 (function(){})() 这是个什么东西?

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

前言

  1. 背景

因为最近在倒腾cesium上的某个东西,但是这个东西是原生的写法,不是es6的module方式,导入导出的形式,所以免不了要去看下这个东西(插件)的源码,看看能不能改成 es6的形式,然后看到了(function(){...})(),如下图

image.png

印象中,这个(function(){...})() 还是早期学JS的时候,当时老师是说,把要初始化的东西写在这个函数的{}中,当时也没多想,老师说就照写,后来接触到了Vue,感觉Vue的 mounted极像这个(function(){...})(),后来用vue开发了一阵子,或多或少的接触到Vue中引入的第三方库,也常常看到(function(){...})()出现在我的视线里。

比如 axios就是这种(function(){...})()形式

image.png

leaflet也是:

image.png

还有!function开头的形式:

image.png

这次就好好复习下(function(){...})()

开始,立即执行函数

(function(){...})()javascript立即执行函数的常见写法,它还有一个兄弟:(function(){…}())

初次看到这两种形式的立即执行函数,是不是很容易搞混,其实也很简单,就是看function 关键字前的 '(' , 它的另一半 ')' 。是放在了最末尾,还是没有放在最末尾 区分 看下图。

image.png

讲立即执行函数,免不了要讲下这个函数,是个什么东西, 函数

  • 函数声明 (可被提升)
  • 匿名函数
  • 函数表达式 (不可被提升,但是表达式后面可以加括号表示立即调用该函数)

函数声明:

function fnName () {…};
复制代码

使用function关键字声明一个函数,再指定一个函数名参数列表方法体,叫函数声明。

匿名函数:

function () {...};
复制代码

使用function关键字声明一个函数,但未给函数命名,所以叫匿名函数,匿名函数属于函数表达式,匿名函数有很多作用,赋予一个变量则创建函数,赋予一个事件则成为事件处理程序或创建闭包等等。

函数表达式:

var fnName = function () {…};
复制代码

使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量,叫函数表达式,这是最常见的函数表达式语法形式。

理解立即执行函数

立即执行函数,字面理解,就是要把函数,立刻马上执行

这又分为

  1. 函数声明类型的 函数执行
  2. 匿名函数类型的 函数执行
  • 函数声明类型的 函数执行
fnName(); 
function fnName(){ ... } 
//正常,因为‘提升’了函数声明,函数调用可在函数声明之前 

fnName(); 
var fnName=function(){ ... } 
//报错,变量fnName还未保存对函数的引用,函数调用必须在函数表达式之后
复制代码

解释:

JS中的函数声明提升概念

  • Javascript引擎在解析javascript代码时会函数声明提升(Function declaration Hoisting)当前执行环境(作用域)上的函数声明,而函数表达式必须等到Javascirtp引擎执行到它所在行时,才会从上而下一行一行地解析函数表达式。

  • 函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以fnName()形式调用 。

所以上方的代码 会执行出 注释中的结果。我们看下面控制台实际执行的结果,也可以看出:

image.png

  • 匿名函数类型的 函数执行
// 第一种情况
(function(a){ 
    console.log(a); // chrome浏览器 输出123,使用()运算符 具体控制台打印示例,看下方图片
})(123); 

// 第二种情况
(function(a){ 
    console.log(a); // chrome浏览器 输出123,使用()运算符 具体控制台打印示例,看下方图片
}(123));

// 第三种情况
!function(a){ 
    console.log(a); // chrome浏览器 输出123,使用 !运算符 具体控制台打印示例,看下方图片
}(123); 
// 第四种情况
+function(a){ 
    console.log(a); // chrome浏览器 输出123,使用 + 运算符 具体控制台打印示例,看下方图片
}(123); 
// 第五种情况
-function(a){ 
    console.log(a); // chrome浏览器 输出123,使用 - 运算符 具体控制台打印示例,看下方图片
}(123); 

var fn=function(a){ 
    console.log(a); // chrome浏览器 输出123,使用 = 运算符 具体控制台打印示例,看下方图片
}(123)
复制代码

image.png

image.png

image.png

image.png

image.png

image.png

看着输出结果,你就会发现:

function前面加!、+、 - 。都可以起到函数定义后立即执行的效果,而()、!、+、-、=等运算符,都将函数声明转换成函数表达式,消除了javascript引擎识别函数表达式函数声明歧义告诉javascript引擎这是一个函数表达式,不是函数声明,可以在后面加括号,并立即执行函数的代码。

加括号最安全的做法,因为!、+、-运算符还会和函数的返回值进行运算,有时造成不必要的麻烦。

おすすめ

転載: juejin.im/post/7054411105493319717