JavaScript——(function(){})()立即执行函数解析
要理解立即执行函数(function(){})(),先了解些函数的基本概念(函数声明、函数表达式、匿名函数)。
函数声明:使用function声明函数,并指定函数名。
function setFn() {// coding
}
函数表达式:使用function声明函数,但未指定函数名,将匿名函数赋予一个变量。
var setFn = function() {// coding
}
匿名函数:使用function关键字声明函数,但未指定函数名。匿名函数属于函数表达式,匿名函数有很多作用,赋予一个变量则创建函数,赋予一个事件则成为事件处理程序或创建闭包等等。
function() {// coding
}
函数声明与函数表达式的不同在于:
1. 函数声明可在当前作用域下提前调用执行,函数表达式需等执行到该函数后,方可执行,不可提前调用。
setFn()
function setFn() {// coding
}
// 正常,函数声明可提前调用setFn()
var setFn = function() {// coding
}
// 报错,setFn未保存对函数的引用,函数调用需放在函数表达式后面
2. 函数表达式可直接在函数后加括号调用。
var setFn = function() {console.log(2)
}()// 2 解析至此,可直接执行调用
立即执行函数(function(){})()可以看出很像函数表达式的调用,但为什么要加括号呢?如果不加括号:
function(){console.log(1)
}()// 报错,函数需要函数名解析: 虽然匿名函数属于函数表达式,但未进行赋值,所以javascript解析时将开头的function当做函数声明,故报错提示需要函数名
立即执行函数里面的函数必须是函数表达式,所以由var setFn = function() {}()可以理解为在匿名函数前加了 = 运算符后,将函数声明转化为函数表达式,所以拿!,+,-,()...等运算符来测试下是否如此。
!function(){console.log(1)
}()
// 1+function(){console.log(2)
}()
// 2-function(){console.log(3)
}()
// 3(function(){console.log(4)
})()
// 4
由此可见,加运算符确实可将函数声明转化为函数表达式,而之所以使用括号,是因为括号相对其他运算符会更安全,可以减少不必要的麻烦。
立即执行函数与正常函数传参形式是一致的。
(function(a, b){console.log(a + b);
})(1, 2)
// 3
(function(){}())这样写的好处是在内部定义的变量不会跟外部的变量有冲突,达到保护内部变量的作用。jquery等好多库里面就好多使用的这种方式,然后再return一个变量,详情可以查看另一篇博文https://blog.csdn.net/xcymorningsun/article/details/85234232
————————————————————————————————————————————————————
关于保护内部变量闭包问题,这个可以看下面的例子
循环中的闭包
一个常见的错误出现在循环中使用闭包,假设我们需要在每次循环中调用循环序号
for(var i = 0; i < 10; i++) {setTimeout(function() {console.log(i); }, 1000);
}
上面的代码不会输出数字 0
到 9
,而是会输出数字 10
十次。
当 console.log
被调用的时候, 匿名函数保持对外部变量 i
的引用,此时 for
循环已经结束, i
的值被修改成了 10
.
为了得到想要的结果,需要在每次循环中创建变量 i
的 拷贝。
避免引用错误
为了正确的获得循环序号,最好使用 匿名包裹器( 译者注:其实就是我们通常说的自执行匿名函数)。
for(var i = 0; i < 10; i++) {(function(e) {setTimeout(function() {console.log(e); }, 1000);})(i);
}
外部的匿名函数会立即执行,并把 i
作为它的参数,此时函数内 e
变量就拥有了 i
的一个拷贝。
当传递给 setTimeout
的匿名函数执行时,它就拥有了对 e
的引用,而这个值是 不会被循环改变的。
有另一个方法完成同样的工作;那就是从匿名包装器中返回一个函数。这和上面的代码效果一样。
for(var i = 0; i < 10; i++) {setTimeout((function(e) {return function() {console.log(e);}})(i), 1000)
}
JavaScript——(function(){})()立即执行函数解析相关推荐
- js中(function(){…})()立即执行函数写法理解
js中(function(){-})()立即执行函数写法理解 javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法 ...
- JavaScript中立即执行函数实例详解 转载 作者:李牧羊
javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解.这篇文章 ...
- JavaScript 之 立即执行函数
1.定义 声明一个函数,并立即调用这个函数,此时这个函数就是立即执行函数,简单来说就是定义函数之后立即执行该函数.立即执行函数一般也写成匿名函数的形式,匿名函数写法为 function(){},就 ...
- JavaScript之立即执行函数
我们知道,在一般情况下,函数必须先调用才能执行,如下所示,我们定义了一个函数,并且调用, function fn(){console.log(1);}fn(); 打印结果为: 如果不调 ...
- 全网最详细JavaScript防抖、节流函数解析
防抖与节流 防抖与节流 防抖 作用与简介 实现 核心与细节 应用场景 节流 作用与简介 实现 核心与细节 应用场景 防抖与节流 防抖 作用与简介 在一个周期T内,如果重复的进行某种响应操作,在不设置防 ...
- JavaScript ES6立即执行函数
立即执行函数 看过jQuery源码的人应该知道,jQuery开篇用的就是立即执行函数.立即执行函数常用于第三方库,好处在于隔离作用域,任何一个第三方库都会存在大量的变量和函数,为了避免变量污染(命名冲 ...
- javascript 匿名自执行函数
有一种匿名函数可以自动执行,这种函数定义如下: (function(){//执行一些语句 })(); 也可以为函数添加参数,语法格式如下: (function(arg_1,arg_2,...arg_n ...
- jQuery自执行函数以及封装工具类的方法
自执行函数 javaScript的自执行函数主要用于保护内部变量不被外部声明污染,自执行函数的结构大致如下:(function(){})();其中,第一个括号使编译器编译该函数体,第二个括号另函数执行 ...
- 深入理解javascript中的立即执行函数(function(){…})()
2019独角兽企业重金招聘Python工程师标准>>> javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各 ...
最新文章
- SMOTE过采样方法
- lc171. Excel Sheet Column Number
- 前端跨域通信的几种方式
- C\C++不经意间留下的知识空白------宏
- Spring3.0包描述
- MTK 驱动开发(24)---camera模块的制作
- 大数据时代时代舍恩伯格书资源_大数据时代的特征和思维
- 计算机的五大组成部分(计组学习一)
- 全球AI芯片企业排行:英伟达第1,华为第12(七家中国公司入围Top24)
- yii2 联表查询时,查询关联表的字段时,使用asArray方法
- JavaScript时间格式化工具函数
- JDK和JRE安装与下载
- 一步一步超级详细的zabbix安装教程
- 我是个骄傲的intj
- 深度学习(6): RNN
- 苹果为M1 MacBook Air/Pro提供自助维修服务 维修成本更低
- C++调用Python及间接调用Python三方库
- PASCAL VOC2012数据集
- 46、W25Q128 存储器工作原理
- 腾讯音乐(K歌)的粗排模型
热门文章
- Git:本地生成SSH KEY,并关联到git仓库
- 计算机 学术论文写作,计算机辅助学术论文写作系统的研制策略与方法.pdf
- 使用Mybatis如何对Mysql进行分页功能?
- PCL之常用开源数据集汇总
- python操作excel命令_python excel操作总结
- inception mysql 使用_mysql 审核引擎 goInception 的基本使用
- yum -y install php-mysql 版本冲突
- spring boot初体验(三)Spring AOP
- Shell脚本学习-阶段七-信息过滤磁盘分区
- 《深入理解Nginx:模块开发与架构解析》一3.3 如何将自己的HTTP模块编译进Nginx...