JavaScript中立即执行函数实例详解
前言
js立即执行函数可以让你的函数在创建后立即执行,js立即执行函数模式是一种语法,可以让你的函数在定义后立即被执行,这种模式本质上就是函数表达式(命名的或者匿名的),在创建后立即执行。
( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到函数定义后立即执行的目的,后来发现加括号的原因并非如此。
下面话不多说了,来一起看看详细的介绍吧。
通常我们声明一个函数有以下几种方式:
// 声明函数f1 function f1() { console.log("f1"); } // 通过()来调用此函数 f1(); //一个匿名函数的函数表达式,被赋值给变量f2: var f2 = function() { console.log("f2"); } //通过()来调用此函数 f2(); //一个命名为f3的函数的函数表达式(这里的函数名可以随意命名,可以不必和变量f3重名),被赋值给变量f3: var f3 = function f3() { console.log("f3"); } //通过()来调用此函数 f3();
如果你看过一些自定义控件的话你会发现他们大多数都是沿用这种写法:
(function() { ``` // 这里开始写功能需求 })();
这是我们常说的立即执行函数(IIFE),顾名思义,也就是说这个函数是立即执行函数体的,不需要你额外去主动的去调用,一般情况下我们只对匿名函数使用IIFE,这么做有两个目的:
一是不必为函数命名,避免了污染全局变量
二是IIFE内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
如果看到这两句话无法理解,那么先从IIFE的运行原理说起。
因为IIFE通常用于匿名函数,这里就用简单的匿名函数作为栗子:
var f = function(){ console.log("f"); } f();
我们发现这里f只是这个匿名函数的一个引用变量,那么既然f()能够调用这个函数,我把f替换成函数本身可以么:
function(){ console.log("f"); }();
运行之后得到如下结果:
Uncaught SyntaxError: Unexpected token (
产生这个错误的原因是,Javascript引擎看到function关键字之后,认为后面跟的是函数声明语句,不应该以圆括号结尾。解决方法就是让引擎知道,圆括号前面的部分不是函数定义语句,而是一个表达式,可以对此进行运算,这里区分一下函数声明和函数表达式:
1、函数声明(即我们通常使用function x(){}来声明一个函数)
function myFunction () { /* logic here */ }
2、函数表达式(类似以这种的形式)
var myFunction = function () { /* logic here */ }; var myObj = { myFunction: function () { /* logic here */ } };
小学我们就学过用()括起来的表达式会先执行,就像下面这样:
1+(2+3) //这里先运行小括号里面的内容没有意见撒
其实在javascript中小括号也有相似的作用,Javascript引擎看到function关键字会认为是函数声明语句,那么如果Javascript引擎优先看到小括号会怎么样:
//用小括号把函数包裹起来 (function(){ console.log("f"); })();
函数成功执行了:
f //控制台输出
这种情况下Javascript引擎就会认为这是一个表达式,而不是函数声明,当然要让Javascript引擎认为这是一个表达式的方法还有很多:
!function(){}(); +function(){}(); -function(){}(); ~function(){}(); new function(){ /* code */ } new function(){ /* code */ }() // 只有传递参数时,才需要最后那个圆括号。 ……
回到前面的问题,为什么说IIFE这种形式避免了污染全局变量,如果你见过别人写的jquery插件,里面通常会有类似这样的代码:
(function($){ ``` //插件实现代码 })(jQuery);
这里的jquery其实是该匿名函数的参数,联想一下我们调用匿名函数时候是用f()那么匿名带参数的就是f(args)对吧,这里把jquery作为参数传入该函数,那么在函数内部使用形参$的时候就不会影响到外部环境,因为有些插件也会用到$这个限定符,你在这个函数内部可以随意折腾。
以上,在此过程中参考了以下两篇文章:
javascript立即执行某个函数:插件中function(){}()再思考
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
- jquery 操作css 选择器
- 主页后台源码及释义
- [C#2] 3-局部类型、属性访问器保护级别、命名空间别名限定符
- (2013.09更新)最新W3School 离线完整版CHM 电子书下载
- [C#2] 1-泛型
- .NET4.0的可扩展缓存系统
- 让WordPress 在RSS 中Feed 截断文字输出
- [C#1] 11-接口
- jquery 标签中的属性操作
- 使用MongoDB存储访问者信息
- 解决WordPress 打开Feed页面“This page contains the following errors…”的问题
- jquery表单属性筛选元素
- [C#1] 10-事件
- Windows 7的VPC虚拟机自动不与主机时间同步的解决办法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Vuex的简单入门
- 听说Mysql你很豪横?-------------管理MySQL数据库基本操作命令
- Axios安装封装api接口
- 排障集锦:九九八十一难之第七难!mysql数据库登录密码忘记了
- Css实现上下无限跳动
- 排障集锦:九九八十一难之第八难!ERROR 2002 (HY000): Can‘t connect to local MySQL server
- Vue Router配置参数、404页面
- 机器学习之决策树三-CART原理与代码实现
- Vue Router路径切换过渡动画
- 听说Mysql你很豪横?-------------深入解析mysql数据库中的索引!
- 听说Mysql你很豪横?-------------深入解析mysql数据库中的事务!
- Struts2笔记
- Vue Router实现路由嵌套单页面展示
- 排障集锦:九九八十一难之第九难!mysql备份恢复路上的小插曲
- jQuery限制复选框checkbox的选中次数