全局变量与局部变量

在说闭包之前先说明全局变量与局部变量

  • 全局变量:变量声明时如果不使用 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

示例解析:

  1. 变量 add 指定了函数自我调用的返回字值;
  2. 自我调用函数只执行一次。设置计数器为 0。并返回函数表达式;
  3. add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器;
  4. 这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能;
  5. 计数器受匿名函数的作用域保护,只能通过 add 方法修改;
  6. 闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。

总结:

闭包就是一个函数引用另一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会增加内存消耗。

或者说闭包就是子函数可以使用父函数的局部变量,还有父函数的参数。

详解javascript中的闭包的更多相关文章

  1. 详解javascript中的this对象

    详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...

  2. 【转】详解JavaScript中的this

    ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...

  3. 详解 javascript中offsetleft属性的用法(转)

    详解 javascript中offsetleft属性的用法 转载  2015-11-11   投稿:mrr    我要评论 本章节通过代码实例介绍一下offsetleft属性的用法,需要的朋友可以做一 ...

  4. (转载)详解Javascript中prototype属性(推荐)

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...

  5. 详解JavaScript中的原型

    前言 原型.原型链应该是被大多数前端er说烂的词,但是应该还有很多人不能完整的解释这两个内容,当然也包括我自己. 最早一篇原型链文章写于2019年07月,那个时候也是费了老大劲才理解到了七八成,到现在 ...

  6. 详解js中的闭包

    前言 在js中,闭包是一个很重要又相当不容易完全理解的要点,网上关于讲解闭包的文章非常多,但是并不是非常容易读懂,在这里以<javascript高级程序设计>里面的理论为基础.用拆分的方式 ...

  7. 【转】详解JavaScript中的异常处理方法

    有三种类型的编程错误:(1)语法错误和(2)运行时错误(3)逻辑错误:语法错误: 语法错误,也被称为解析错误,在编译时进行传统的编程语言,并出现在JavaScript解释时. 例如,下面一行将导致一个 ...

  8. 详解JavaScript中的Event Loop(事件循环)机制

    前言 我们都知道,javascript从诞生之日起就是一门单线程的非阻塞的脚本语言.这是由其最初的用途来决定的:与浏览器交互. 单线程意味着,javascript代码在执行的任何时候,都只有一个主线程 ...

  9. 详解JavaScript中的arc的方法

    今天说说JavaScript在网页中画圆的函数arc! 一.arc所需要的参数设置 1 arc(x, y, radius, startAngle, endAngle, counterclockwise ...

随机推荐

  1. HTTP状态码、请求方法、响应头信息

    HTTP状态码 当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求.当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应 ...

  2. CSS3 banner图片的标签效果

    放body看,你懂的:)

  3. AspNet Core Web 应用程序的启动 当项目中 没有Startup.cs 类如何设置启动 配置等等

    感叹: Core 16年6月1号 在中国宣布上线 到现在已经快经历两年时间了,目前版本已经到了2.0 就目前的前景来看,个人感觉 到2020年才可能有所起色,等到Core更成熟 个人看法:在.net这 ...

  4. 一秒搞定mysql的远程登录

    执行下面命令! mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'mypw' WITH GRANT OPTION ; ...

  5. XCode v9.6.2017.0830

    新生命团队基础框架X组件,包括网络.数据库.安全.多线程.反射.序列化.模版引擎.服务代理.远程过程调用等模块,包括Mvc后台魔方.超级码神工具.消息队列等子系统,支持Mono/Android/iOS ...

  6. 【干货】分享几个写 demo 的思路

    好久没有动笔,最近发现了一个新的写 demo 的思路,仔细一想,自己仿佛积累了不少写 demo 的思路和想法,总结一下,抛砖引玉. 本文所说 demo 主要分以下三种: 本地 demo 外链 demo ...

  7. python 组合样例

    class Bill(): def __init__(self, description): self.description = description class Tail(): def __in ...

  8. JAVA入门(1.JAVA平台应用 2.核心概念:JVM,JDK,JRE 3.搭建JAVA开发环境 4.学习JAVA的原则)

    主要内容: 1.JAVA平台应用 2.核心概念:JVM,JDK,JRE 3.搭建JAVA开发环境 4.学习JAVA的原则 JAVA的平台应用 JAVA的平台应用分为3个部分: 一.JAVA SE,主要 ...

  9. uImage和zImage的区别

    1.各种文件的意义 vmlinux  编译出来的最原始的内核文件,未压缩. zImage   是vmlinux经过gzip压缩后的文件. bzImage bz表示“big zImage”,不是用bzi ...

  10. vb代码之-------当窗体BorderStyle属性为0时,添加窗口预览到任务栏

    入吾QQ群183435019 (学习 交流+唠嗑) 有很多时候,我们为了美观,将会自己画一个标题栏,这时候我们会把原来的标题栏取消掉,最简单的方法是吧窗体的BorderStyle设置成为0, 然后自己 ...