javascript闭包和立即执行函数的作用
一、闭包——closure
先看一个闭包的例子。我们想实现一个计数器,最简单的方法就是定义一个全局变量,计数的时候将其加1。但是全局变量有风险,哪里都有可能不小心改掉它。那局部变量呢,
它只在函数内部有效,函数调用完后它就没了,而且全局没法使用。那我们用想让计数器全局使用,又不想让这个变量被随便修改怎么办。这就需要闭包了:
function count(){
var i=0;
return function () {
return ++i;
}
}
这个例子实现了一个简单的计数器。函数"count()"定义了一个局部变量“i”,并返回一个内部匿名函数。因为是内部函数,所以它可以访问其外部函数的局部变量“i”,并且将其加1并返回。让我们看下怎么使用这个计数器。
c1 = count();
console.log(c1()); //print1
console.log(c1()); //print2
console.log(c1()); //print3 c2 = count();
console.log(c2()); //print1
每次调用“count()”函数后就会生成一个计数器,而且不同的计数器之间不干扰。因为两次调用同一个函数,创建的栈是不同的,因此栈内的局部变量是不同的。上例中,我们生成了全局计数器“c1”和“c2”,他们都是不带参数的函数,即“count()”中返回的匿名函数。此后每次调用计数器,比如“c1()”,计数器就会自增1并返回。但是由于“count()”函数已经调用完毕,我们将无法通过任何其他办法去修改“count()”中变量“i”的值。这就是闭包最实用的功能,就是将你想操作的变量或对象隐藏起来,只允许特定的方法才能访问它。
二、立即执行函数
n年前看到jQuery的源码时,很好奇它的最外层结构是这样的(现在已经不一样了):var jQuery = (function(){……})();
作为前端小白的我,实在想不通这是为什么,好好定义一个函数,为啥还要调用它。大家知道javascript在es6之前并不严格支持面向对象。js的对象其实就是一个map,比如下面的例子:
var car = {
speed:0,
start:function(){ this.speed=40; },
getspeed:function(){ return this.speed; }
};
car.start();
console.log(car.getspeed()); //print 40
这个对象有其成员变量“speed”及成员函数“start”和“getspeed”,但是它的成员变量没有私有化,同时它也没有办法被继承。要实现对象的继承,你可以使用构造函数和原型继承。但怎么才能将成员变量私有化来实现对象的封装呢(而且有时候我们也不想那么麻烦使用原型)?有心的读者看了上面闭包的介绍,肯定马上有想法了。对,使用闭包!
function car() {
var speed = 0;
return { //返回的是一个对象
start:function() {
speed = 50;
},
getspeed:function () {
return speed;
}
}
} var car1 = car();
car1.start();
console.log(car1.getspeed()); //print 50
说了那么多,跟立即执行函数有什么关系呢。你再仔细看看上面的例子,你有了闭包函数来帮你创建“car”对象,这个函数就类似于工厂方法,它可以根据你的需要创建多个不同的对象。不过开发的时候经常遇到这样的情况,就是我们希望对象只有一份,比如jQuery库的对象,它必须确保整个程序只有一份,多了也没有。在后端开发模式中,这叫单例模式,可以通过私有化构造函数来实现,那么在js里呢?
既然函数没法私有化,那么唯一的办法就是让这个工厂方法能且只能被调用一次。不能多次调用,那这个函数一定要是匿名函数;而且能被调用一次,那就必须在声明的时候立马执行。这时候,我们就可以邀请立即执行函数出场了:
var car = (function () {
var speed = 0;
return {
start:function () {
speed=60;
},
getspeed:function () {
return speed;
}
}
})(); car.start();
console.log(car.getspeed()); //print 60
很多人一开始会看错,认为对象“car”是一个函数,其实它是这个匿名的工厂方法执行完返回的对象,该对象拥有“start”和“getspeed”两个成员函数,而这两个函数所需要访问的“speed”变量对外不可见。同时你无法再次调用这个匿名的工厂方法来创建一个相同的对象。是不是很神奇?一个单例的,有着私有成员的对象就这么建好了。
立即执行函数还有一种写法就是:
var car = (function () {
……
}());
本篇文章的出处:http://www.bjhee.com/js-closure-iif.html
javascript闭包和立即执行函数的作用的更多相关文章
- 深入理解javascript中的立即执行函数(function(){…})()
投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...
- Javascript 闭包与高阶函数 ( 二 )
在上一篇 Javascript 闭包与高阶函数 ( 一 )中介绍了两个闭包的作用. 两位大佬留言指点,下来我会再研究闭包的实现原理和Javascript 函数式编程 . 今天接到头条 HR 的邮件,真 ...
- javascript中的立即执行函数(function(){…})()
javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包 ...
- 深入理解javascript中的立即执行函数
这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见,需要的朋友可以 ...
- javascript (function() { /* code */ })() 自执行函数
(function(){ function a(){ alert("a"); } })(); 自执行匿名函数: 常见格式:(function() { /* code */ })() ...
- [转]Javascript中的自执行函数表达式
[转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...
- Javascript 闭包与高阶函数 ( 一 )
上个月,淡丶无欲 让我写一期关于 闭包 的随笔,其实惭愧,我对闭包也是略知一二 ,不能给出一个很好的解释,担心自己讲不出个所以然来. 所以带着学习的目的来写一写,如有错误,忘不吝赐教 . 为什么要有闭 ...
- 理解javascript中的立即执行函数(function(){})()
之前看了好多代码,都有用到这种函数的写法,但是都没认真的去想为什么会这样写,今天开始想学习下jquery的源码,发现jquery也是使用这种方式,用(function(window, undefine ...
- 【JavaScript】 js立即执行函数
( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,一般理解是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到函 ...
随机推荐
- CMDB实现的四种方式
第一种(agent): 这种方式是通过向每一台服务器安装agent脚本,然后通过中控机的API,来收集所需要的数据,最后放到数据库中,在通过web的方式显示出来. 实现流程图: 1.录入资产(主机名, ...
- 前端 javascript 定时器
setInterval("执行的代码",间隔时间)毫秒单位 每5秒一次会提示出弹框 <!DOCTYPE html> <html lang="en&quo ...
- Swift学习——Swift基础具体解释(一)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zhenyu5211314/article/details/34807025 注:由于基础部分在Swi ...
- 细说PHP7
PHP7带来的新东西 1.类型的声明. 可以使用字符串(string), 整数 (int), 浮点数 (float), 以及布尔值 (bool),来声明函数的参数类型与函数返回值. declare(s ...
- Linux系统——本地定制化yum仓库部署
1)开启yum仓库配置文件 /etc/yum.conf的keepcache功能 (开启一个新的虚拟机) 将keepcache=0改为1,修改配置文件后重新清空缓存(1默认下载的安装包不删除,才可以实现 ...
- 基于EasyUI 快速搭建权限管理平台
前言: 一.用户角色权限设计思路: <1>不同职责的人员,对于系统操作的权限应该是不同;<2>可以对“组”进行权限分配;<3>权限管理系统应该是可扩展的;<4 ...
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree
地址:http://codeforces.com/contest/842/problem/C 题目: C. Ilya And The Tree time limit per test 2 second ...
- sqlite常用的命令-增删改查
一.查看版本信息: #sqlite3 -version 二.sqlite3常用命令 1.当前目录下建立或打开test.db数据库文件,并进入sqlite命令终端,以sqlite>前缀标识: 2. ...
- JS正则表达式从入门到入土(1)—— REGEXP对象
REGEXP对象 JavaScript通过内置对象RegExp支持正则表达式,有两种方法实例化RegExp对象. 1.字面量 2.构造函数 字面量 字面量是直接通过/.../创建RegExp对象实例. ...
- Web安全学习笔记之Kali配置国内软件更新源
0x0 前言 Kali安装完成后,默认是国外官方的更新源,更新速度4kb/s太酸爽了... 0x1 把更新源设置为国内阿里云或者中科大的镜像源 命令行:leafpad /etc/apt/sources ...