今天看了关于js闭包方面的文章,还是有些云里雾里,对于一个菜鸟来说,学习闭包确实有一定的难度,不说别的,能够在网上找到一篇优秀的是那样的不易。

  当然之所以闭包难理解,个人觉得是基础知识掌握的不牢,因为闭包牵扯到一些前面的东西,比如作用域\等等,如果连基本的作用域都没有弄清楚,自然不可能搞懂闭包,还有就是对js的实践比较少,因为你根本就不知道什么时候要用这东西,自然谈不上对闭包的深刻理解。

  今天我就简单的说说我目前所理解的闭包,当然可能不完全正确,但是我相信会给你一定的启发。

  首先我们来谈谈js中的变量,如果你不知道我为什么要说这些,那么你根本没有掌握js的基础,建议回头复习。

js中分:全局变量 和 局部变量

  全局变量:可以在任意位置访问的量就叫全局变量

    

1 var age = 20;
2 function a(){
3 console.log(age); >>20
4 }
5 a();

  局部变量:函数中用var定义的变量,只能在函数中访问这个变量,函数外部访问不了。

1 function a(){
2 var age = 20;
3 }
4 a();
5 console.log(age); >> Uncaught ReferenceError: age is not defined

注意点1:在函数中如果不使用var定义变量那么js引擎会自动添加成全局变量。

注意点2:全局变量从创建的那一刻起就会一直保存在内存中,除非你关闭这个页面,局部变量当函数运行完以后就会销毁这个变量,假如有多次调用这个函数它下一次调用的时候又会重新创建那个变量,既运行完就销毁,回到最初的状态,简单来说局部变量是一次性的,用完就扔,下次要我再重新创建。

 

函数的相关知识点:

1. 一个函数内可以嵌套多个函数

    2. 函数里面的子函数可以访问它上级定义的变量,注意不只是一级,如果上级没有会继续往上级找,直到找到为止,如果找到全局变量到找不到就会报错。

    

1 function a(){
2 var name = "追梦子";
3 function b(){
4 console.log(name); >> "追梦子"
5 }
6 b();
7 }
8 a();

    3. 函数的另外一种调用形式,你可以把它叫做自调用,自己调用自己,达到自执行的效果。

   

1 var a = 0;
2 (function(){
3 console.log(++a); >>1
4 })()

这种方式用()把内容包裹起来,后面的()表示执行这个函数,可能你会问为什么要把函数包起来,如果不包裹起来,js会把它当作函数声明来处理,如果包裹起来就是表达式,还没有看懂就上网查吧。

开始我们正式闭包部分---------------------------- 币包 ---------------像钱包一样的东西,可以把东西包裹起来----------

首先我们来看看为什么需要学习闭包,加以理解 -- 0 v  0- -

1 function a(){
2 var num = 0;
3 console.log(++num);
4 }
5 a(); >>1
6 a(); >>1

上面代码输出了两次1,为什么呢?如果你有看我上面的关于变量部分肯定能够想到个大概。

  前面我们说过了函数执行完以后,里面的变量(即局部变量)就会销毁,下一次运行又会重新创建那个变量,所以虽然你第一次++num了但是这个变量在第一次执行完毕以后就被销毁了。

那么我们怎么样才能确保第一次的变量不被销毁,那么就需要我们的闭包出场了。

温馨提示:JavaScript中有回收机制,函数没有被引用执行完以后这个函数的作用域就会被销毁,如果一个函数被其他变量引用,这个函数的作用域将不会被销毁,(简单来说就是函数里面的变量会被保存下来,你可以理解成全局变量。)

…………………………………………………………………………………… 当 当 当 ................. 下面有请我们的币包同志

function a(){
var aa = 0;
function b(){
aa ++;
console.log(aa);
}
return b;
}
var ab = a();
ab(); //1
ab(); //2

看到了吧里面的变量的值没有被销毁,因为函数a被外部的变量ab引用,所以变量aa没有被回收。

如果某个函数被它的父函数之外的一个变量引用,就形成了一个闭包

还有一种更为常用的闭包写法

var bi = (function(){
var a = 0;
function b(){
a ++;
console.log(a);
}
return b;
})(); bi(); //1
bi(); //2
bi(); //3

执行过程分析:

  首先把一个自执行函数赋值给了bi,这个自执行函数运行完成以后就bi的值就变成了

function b(){
a ++;
console.log(a);
}

  因为我们在上面的代码return回去了b,然后因为这个自执行函数被bi引用所以里面的变量a并没有因为这个自执行函数执完而销毁,而是保存到了内存中,所以我们多次打印bi()就成了1、2、3

下面我来说一个闭包的使用场景吧。

  没有使用闭包的版本

window.onload = function(){
var ul = document.getElementsByTagName("ul")[0];
var li = ul.getElementsByTagName("li");
for(var i=0;i<li.length;i++){
li[i].onclick = function(){
console.log(i); //不管我怎么点都是返回6
}
}
}

  使用了闭包的版本

window.onload = function(){
var ul = document.getElementsByTagName("ul")[0];
var li = ul.getElementsByTagName("li");
for(var i=0;i<li.length;i++){
(function(i){
li[i].onclick = function(){
console.log(i); //点击第几个返回第几个
}
})(i)
}
}

、、、、、如果你不理解这个,你只要这样子用就能够达到效果。

这也只是简单的介绍了一下,后面将会在闭包的高级部分讲解。如果你对闭包有更深的理解可以pm我。

s中的闭包的更多相关文章

  1. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  2. 【原】理解javascript中的闭包

    闭包在javascript来说是比较重要的概念,平时工作中也是用的比较多的一项技术.下来对其进行一个小小的总结 什么是闭包? 官方说法: 闭包是指有权访问另一个函数作用域中的变量的函数.创建闭包的常见 ...

  3. 难道这就是JavaScript中的"闭包"

    其实对于JavaScript中的"闭包"还没真正理解,这次在实际Coding中似乎遇到了"闭包"的问题,仅此摘录,以待深究. 表现为jQuery的post方法回 ...

  4. 【原】如何在jQuery中实现闭包

    原生JS中,闭包虽好用,但是很难用好,在jQuery中一样,都有一些点需要我们注意.jQuery中使用闭包的常见情况有以下几种: 1.$(document).ready()的参数 我们在写jQuery ...

  5. 说说Python中的闭包 - Closure

    转载自https://segmentfault.com/a/1190000007321972 Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西 ...

  6. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  7. javascript中的闭包解析

    学习javaScript已经有一段时间了,在这段时间里,已经感受到了JavaScript的种种魅力,这是一门神奇的语言,同时也是一门正在逐步完善的语言,相信在大家的逐步修改中,这门语言会逐步的完善下去 ...

  8. javascript中的闭包,超简单论述,保证小学生必懂

    js中的闭包已经有很多论断了,大家伙有没有听懂了,先引用一片比较高端 的 ”汤姆大叔“  深入理解JavaScript系列(16):闭包(Closures) 好了,为了引起大家的兴趣,先来小诗一首 v ...

  9. 详解js中的闭包

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

  10. js中的闭包之我理解

    闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的 ...

随机推荐

  1. C# WinForm Webbrowser 强制所有网页链接在同一页面打开或者在TabControl中弹出新窗口(续)

    上面那个文写的如同粑粑一样 效果图 Winfrom 中添加这个类就好了 using System; using System.Collections.Generic; using System.Com ...

  2. 数据存储 mongodb

    数据存储 mongodb from pymongo import MongoClient import os base_dir = os.getcwd() class MongoPipeline(ob ...

  3. 在CentOS-6.3环境下,利用grub工具手工制作Linux U盘安装盘

    注:此文是本人亲自操作实现后写的心得,同时也是对自己操作的记录. 制作的全过程概况 准备工作: U盘重新分区: 格式化U盘: 安装grub文件到U盘特定的分区: 拷贝镜像中的相关文件到U盘: 安装时设 ...

  4. css清除浮动的8种方法以及优缺点

    浮动会使当前标签产生上浮的效果,同时会影响到前后的标签.父级标签的位置及width height 属性.而且同样的代码,在各种浏览器中效果可能不同,这样让清除浮动更难了.清除浮动引起的问题有很多的方法 ...

  5. leecode刷题(2)-- 买卖股票的最佳时机

    买卖股票的最佳时机 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多 ...

  6. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 …… 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  7. MD5和SHA-1

    MD5和SHA-1都是我们耳熟能详的术语了,很多人可能知道他们跟加密有关系,但是他们是怎么做到加密的,他们各自的特点又是什么.我来简单的讲一讲. MD5和SHA-1都被称作哈希(Hash)函数,用过J ...

  8. 微信小程序之页面之间传递值

    页面之间传值有三种方式 1.url传值 2.本地存储传值 3.全局变量传值 1.url传值: 通过url传值的需要通过option来获取参数值. 更多详情可以访问小程序-navigateTo章节. A ...

  9. 洛谷 P3388 【模板】割点(割顶)

    题目链接 题解 今天复习了一下割点. 关于\(tarjan\)这里不多讲 \(dfn\)和\(low\)数组的定义想必大家都知道 仔细观察一下,可以发现 假设便利\(u->v\)这条边 如果 \ ...

  10. LOJ6519. 魔力环(莫比乌斯反演+生成函数)

    题目链接 https://loj.ac/problem/6519 题解 这里给出的解法基于莫比乌斯反演.可以用群论计数的相关方法代替莫比乌斯反演,但两种方法的核心部分是一样的. 环计数的常见套路就是将 ...