详解javascript中的闭包
| 全局变量与局部变量 |
在说闭包之前先说明全局变量与局部变量
- 全局变量:变量声明时如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义。
- 局部变量:使用var关键字定义
全局变量/局部变量的作用域:
全局变量作用于整个程序,任何一处代码都能访问,局部变量只能用于定义它函数内部。对于其他的函数或脚本代码是不可用的。
全局和局部变量即便名称相同,它们也是两个不同的变量。修改其中一个,不会影响另一个的值。
第二需要知道的预备知识:javascript的作用域,请参考博客javascript基础
| 变量的生命周期 |
全局变量的作用域是全局性的,即在整个JavaScript程序中,全局变量处处都在。
而在函数内部声明的变量,只在函数内部起作用。这些变量是局部变量,作用域是局部性的;函数的参数也是局部性的,只在函数内部起作用,函数一旦执行完毕,局部变量将释放。
先看示例:计数器问题
function add() {
var counter = 0;
counter += 1;
}
add();
add();
add();
// 本意是想输出 3, 但事与愿违,输出的都是 1 !
当我们把局部变量在换成全局变量在看计数器问题
counter=0;
function add() {
counter+=1;
console.log(counter); }
add();
add();
add();//最后结果输出3,本次结果虽然符合我们的要求,但是修改全局变量对于我们程序是不友好的,因为可能在任何一处都可能使用到该全局变量
| 闭包的引入与示例 |
从javascript的作用域我们知道,函数的嵌套可以使得内部函数可以访问到上一层函数的变量,这样我们就可以利用函数的嵌套解决计数器问题。
示例:
function add() {
var counter=0;
function innerAdd() {
counter+=1;
}
innerAdd();
return counter
}
add();
add();
res=add();
console.log(res)
//输出1.,这是因为每次调用add函数时候都把counter进行了重新赋值为0了,如果我们让counter=0只执行一次,那么问题就得到解决了。
| javascript的闭包 |
在javascript中有一类函数是自执行函数,这里我们我们将用它来解决计数器问题;
示例:
var add=(function() {
var counter=0;
return function () {
counter+=1;
console.log(counter )
}
})()
add();
add();
add();
//输出counter值为3
示例解析:
- 变量 add 指定了函数自我调用的返回字值;
- 自我调用函数只执行一次。设置计数器为 0。并返回函数表达式;
- add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器;
- 这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能;
- 计数器受匿名函数的作用域保护,只能通过 add 方法修改;
- 闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。
总结:
闭包就是一个函数引用另一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会增加内存消耗。
或者说闭包就是子函数可以使用父函数的局部变量,还有父函数的参数。
详解javascript中的闭包的更多相关文章
- 详解javascript中的this对象
详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...
- 【转】详解JavaScript中的this
ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...
- 详解 javascript中offsetleft属性的用法(转)
详解 javascript中offsetleft属性的用法 转载 2015-11-11 投稿:mrr 我要评论 本章节通过代码实例介绍一下offsetleft属性的用法,需要的朋友可以做一 ...
- (转载)详解Javascript中prototype属性(推荐)
在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...
- 详解JavaScript中的原型
前言 原型.原型链应该是被大多数前端er说烂的词,但是应该还有很多人不能完整的解释这两个内容,当然也包括我自己. 最早一篇原型链文章写于2019年07月,那个时候也是费了老大劲才理解到了七八成,到现在 ...
- 详解js中的闭包
前言 在js中,闭包是一个很重要又相当不容易完全理解的要点,网上关于讲解闭包的文章非常多,但是并不是非常容易读懂,在这里以<javascript高级程序设计>里面的理论为基础.用拆分的方式 ...
- 【转】详解JavaScript中的异常处理方法
有三种类型的编程错误:(1)语法错误和(2)运行时错误(3)逻辑错误:语法错误: 语法错误,也被称为解析错误,在编译时进行传统的编程语言,并出现在JavaScript解释时. 例如,下面一行将导致一个 ...
- 详解JavaScript中的Event Loop(事件循环)机制
前言 我们都知道,javascript从诞生之日起就是一门单线程的非阻塞的脚本语言.这是由其最初的用途来决定的:与浏览器交互. 单线程意味着,javascript代码在执行的任何时候,都只有一个主线程 ...
- 详解JavaScript中的arc的方法
今天说说JavaScript在网页中画圆的函数arc! 一.arc所需要的参数设置 1 arc(x, y, radius, startAngle, endAngle, counterclockwise ...
随机推荐
- 微信小程序之使用本地接口开发
本文主要讲解如何使用本地接口进行开发,很多人都会遇到这个问题,特别是小程序上线后. 一.解决思路 在小程序开发工具设置网络代理,然后再通过Charles设置代理,将https域名转为本地接口进行访问. ...
- 转:java 可设置最大内存
测试方法:在命令行下用 java -XmxXXXXM -version ,比如:java -Xmx1024M -version命令来进行测试,然后逐渐的增大XXXX的值,如果执行正常就表示指定的内存大 ...
- 12.python进程\协程\异步IO
进程 创建进程 from multiprocessing import Process import time def func(name): time.sleep(2) print('hello', ...
- 2017 年的 人生 hard 模式终于结束了,2018年回归初心
2017 年的 人生 hard 模式终于结束了,2018年回归初心 2017年对于我个人来讲, 毫不夸张的说 算是近十年来除了高考那一年,最最惊心动魄的一年了,没有之一. >>>开篇 ...
- 记录一次APP的转让流程
由于业务需要,需要将开发的App从一个账号(A账号)转移到另一个账号(B账号),这里简单介绍一下转让流程.主要包括两大步骤: 转让方(A账号)提出转让申请 接收方(B账号)接受转让App 如果不想看这 ...
- LeetCode第[16]题(Java):3Sum Closest 标签:Array
题目难度:Medium 题目: Given an array S of n integers, find three integers in S such that the sum is closes ...
- 解决前端开发sublime text 3编辑器无法安装插件的问题
今天在笔记本电脑上安装了个sublime,但是却出现无法装插件的问题.于是稍微在网上查了些资料,并试验了一番,写了如下文章. 安装插件的步骤: 弹出 选中install package 如果出现如下问 ...
- Java_web学习(一) jdk配置
1.下载好jdk1.8.0版本或以上版本 2.配置JAVA_HOME,CLASSPATH,PATH 其中JAVA_HOME必须的 2.1 JAVA_HOME=E:\java\jdk1.8.0_77 ...
- 集合 (set) 的增删改查及 copy()方法
一.集合 1.集合的创建 set1 = set({1,2,'barry'}) set2 = {1,2,'barry'} print(set1,type(set1)) print(set2,type(s ...
- 开发高性能JAVA应用程序基础(内存篇)
虽然Java的垃圾回收和当前高配置的服务器可以让程序员大部分时间忘掉OutOfMemoryError的存在,但是访问量增大后频繁的GC会额外消耗CPU (使用top查看结果为us值高),系统响应速度下 ...