关于javascript闭包的最通俗易懂的理解
这两天在研究闭包,网上一通找,有牛人写的帖子,有普通人写的帖子,但是大多没戳中本小白所纠结的点,而且大多插入了立即执行函数,其实根本不需要的,反而让人产生了误解。这里我用我的方式讲解一下闭包。
1.目的:保证局部变量常驻在内存中,且只能通过固定的方式访问,不可以被所有人访问,算起来也算是个只能被指定对象访问的专用型全局变量。
2.实现方式:在函数f1中返回一个内部定义的函数f2,后通过使用返回出来的函数f2来操作f1中定义的局部变量。
下面我来从各种刁钻的角度来举例详细说明,包学包会!看完例子以后再看上面说的目的和实现方式就会有种豁然开朗的感觉了!
round 1:
function add() {
var x = 0;
return function () {
return ++x;
}
};
/*此处的add()的括号和function add()的括号表达的意思是完全不同的, 在此处add表示上
面定义的函数,add()表示执行一次上面定义的函 数,这一点很关键!执行一次的结果就是返回了函数 function () {return ++x;},但是请注意!这里返回的仅仅是函数本 身,也就是此时函数尚未执行,故此时x=0*/
var temp=add();
//执行一次返回的函数,++x,此时x=1
temp();
//再次执行一次返回的函数,此时x=2,且输出了函数的返回值2,可以在控制台中看到
console.log(temp());
这就完成了闭包了,add函数中的x常驻内存,且我可以在add函数外部通过调用它返回的函数来操作这个x,如果看懂了下面可以不看,如果看了其他帖子有一些其他的异或比如立即执行函数之类的可以看看下面的,你很快就不会疑惑了!
round 2:
//此处temp表示函数add函数本身,但是尚未执行。
var temp = function add() {
var x = 0;
return function () {
return ++x;
}
};
//执行temp函数,返回函数 function () {return ++x;},但尚未执行该函数,故x=0
var temp1 = temp();
//执行temp1,此时执行了一次function () {return ++x;},故x=1
temp1();
//再次执行一次function () {return ++x;},此时x=2,且输出到了控制台
console.log(temp1());
这一回合是为下面的立即执行函数做铺垫,下面立即执行函数版本隆重登场!当当当当!
round 3:
/*仔细看,此处为(fucntion add(){})(),此处执行了立即执行函数,也就是说返回给temp的与round2返回的add函数本身不同,而是返回的 function () {return ++x;}*/
var temp = (function add() {
var x = 0;
return function () {
return ++x;
}
})();
//顺理成章的,这里直接执行temp,就是执行了function () {return ++x;},故x=1
temp();
//同理x=2
console.log(temp());
经过上面三个例子的讲解想必你已经心中有数了,但是肯定还是存在疑惑的,比如说round1中var temp=add();,我不把add()的结果赋给temp直接执行行不行?答案是否定的,有一点一定要认知清楚,函数是对象,这一点至关重要,否则将会走入误区。下面举例说明:
这个是round1的改版:
function add() {
var x = 0;
return function () {
return ++x;
}
};
console.log(add()());//输出1
console.log(add()());//输出1
为什么会这样呢?关键点在于函数是对象,上面实行了两次add()(),在这两次中,add()返回的对象是不一样的,所以他们各自再执行add()()就是为各自的局部变量x加1,所以才两次都输出1,假如改一下
function add() {
var x = 0;
return function () {
return ++x;
}
};
var temp1 = add();
var temp2 = add();
console.log(temp1());//输出1
console.log(temp1());//输出2
console.log(temp2());//输出1
console.log(temp2());//输出2
这样是不是就明白了,同理add函数也不能写成下面这种形式:
function add() {
var x = 0;
return (function () {
return ++x;
})()
};
否则返回的只是一个常量而不是一个对象了。希望这篇文章能给跟我一样在摸索闭包的小白一点启发,嘿嘿嘿
关于javascript闭包的最通俗易懂的理解的更多相关文章
- 深入理解javascript闭包(一)
闭包(closure)是Javascript语言的一个难点.也是它的特色,非常多高级应用都要依靠闭包实现. 一.什么是闭包? 官方"的解释是:闭包是一个拥有很多变量和绑定了这些变量的环境的表 ...
- javascript 闭包(转)
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- JavaScript 闭包整合
初遇闭包感觉很困惑,上网查看了些许介绍,有很多没看懂,就想先对能懂的东西整整 首先觉得要了解闭包,要先对一.JavaScript的变量作用域和作用域链有基本了解 1.变量的作用域分为:全局变量和局部变 ...
- 一篇文章图文并茂地带你轻松学完 JavaScript 闭包
JavaScript 闭包 为了更好地理解 JavaScript 闭包,笔者将先从 JavaScript 执行上下文以及 JavaScript 作用域开始写起,如果读者对这方面已经了解了,可以直接跳过 ...
- JavaScript学习总结——我所理解的JavaScript闭包
一.闭包(Closure) 1.1.什么是闭包? 理解闭包概念: a.闭包是指有权限访问另一个函数作用域的变量的函数,创建闭包的常见方式就是在一个函数内部创建另一个函数,也就是创建一个内部函数,创建一 ...
- JavaScript闭包理解【关键字:普通函数、闭包、解决获取元素标签索引】
以前总觉得闭包很抽象,很难理解,所以百度一下"闭包"概览,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的 ...
- javascript闭包理解
//闭包理解一 function superFun(){ var _super_a='a'; function subfuc(){ console.log(_super_a); } return su ...
- javascript 闭包最简单理解
首先说3点与闭包有关系的东西. 一.变量的作用域 变量的作用域不难理解. 1.函数内部可以访问函数外部的变量,而函数外部不能访问函数内部的变量. 2.如果在函数内定义变量的时候,不加var,那么是全局 ...
- 全面理解Javascript闭包和闭包的几种写法及用途
好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一些实用的东西,主要将闭包的写法.用法和用途. 一.什么 ...
随机推荐
- Emacs 入门(https://www.zybuluo.com/eqyun/note/40788)
下载地址 基本操作(C=Ctrl, M=Alt) C-f 向右移动一个字符 C-b 向左移动一个字符 C-n 移动到下一行 C-p 移动到上一行 M-f 向右移动一个词[对中文是移动到下一个标点符号] ...
- (6)autotools工具的使用
autotools是专门用来生成Makefile的一系列工具,包括autoscan.aclocal.autoheader.autoconf.automake等. (1)autotools ...
- 将CDH中的hive和hbase相互整合使用
一..hbase与hive的兼容版本: hive0.90与hbase0.92是兼容的,早期的hive版本与hbase0.89/0.90兼容,不需要自己编译. hive1.x与hbase0.98.x或则 ...
- webservice传输文件的三种方式
1, 在接口中不定义,直接以附件形式传输. 2, 在接口参数中定义byte[]类型,文件在xml中以base64编码传输. 3, 在接口参数中定义DataHandler类型,然后使用MTOM形式来进行 ...
- 1.html基础知识
1.html定义: html是一种超文本标记语言,“超文本”是指页面可以包含图片.链接.音乐.程序等非文字元素. Html不是一种编程语言. 2.html5的新特性: 用于绘画的canvas元素: 用 ...
- Vsftp服务-实战案例
Vsftp 实验案例一:(本地用户) 试验版本:Linux7.X版本 公司内部现在有一台FTP 和WEB 服务器,FTP 的功能主要用于维护公司的网站内容,包括上传文 件.创建目录.更新网页等等.公司 ...
- 如何增强VR的vection/self-motion?
上一节讲到了vection是给玩家带来“移动感”的因素,它提供良好VR体验的关键之一.那么VR中我们一般用哪些方式来提供vection呢?1 首先来简单了解一下人体和空间相关的感知机制. 视觉线索 v ...
- 浅拷贝&深拷贝的对比
js中两种数据类型 浅拷贝:拷贝就是拷贝指向对象的指针,意思就是说:拷贝出来的目标对象的指针和源对象的指针指向的内存空间是同一块空间,浅拷贝只是一种简单的拷贝,让几个对象公用一个内存,然而当内存销毁的 ...
- 详解http报文(2)-web容器是如何解析http报文的
摘要 在详解http报文一文中,详细介绍了http报文的文本结构.那么作为服务端,web容器是如何解析http报文的呢?本文以jetty和undertow容器为例,来解析web容器是如何处理http报 ...
- kotlin系列文章 --- 2.基本语法
函数 函数定义使用fun关键字,参数格式为:参数:类型,需要声明返回类型 fun sum(a:Int, b:Int): Int{ return a+b } 表达式作为函数体,返回值类型自动推断 fun ...