javascript中闭包概念与用法深入理解

本文实例分析了javascript中闭包概念与用法。分享给大家供大家参考,具体如下:

1.问题的引出,什么时候会遇到闭包?

首先因为JS是没有块状作用域的,但是有函数作用域即函数作为了局部变量之间的界限,不同函数内的局部变量具有独立性,

因为JS没有块状作用域,笔者初学JS时,在事件的监听时,因为不理解JS中局部变量的作用域,犯过不少错误!

(1)JS中的变量作用域

for(var i=0;i<9;i++)
{
}
alert(i) //输出9

我们发现,虽然变量i是块状区域for()内的一个局部变量,但是我们在块级作用域for()外,依然可以得到变量i

(2)JS中的函数作用域

function abc(){
 var a=1;
}
abc();
alert(a);// 会报错,a is not defined

我们发现,在函数外调用函数后,在函数外是无法取到函数里的变量

总结:通过(1),(2),我们加深了对JS中,没有块级作用域只有函数作用域的理解!

举例:如果现在例1:

var a=1
function abc(){
 var a=2;
}
abc();
alert(a) // a=1

特别注意如果例2:

var a=1
function abc(){
a=2;
alert(a);
}
abc();//a=2

对比例1,不同之处在于例2,中 是“a=2"而不是”var a=2“

区别在于如果是var a,则表示在函数中定义变量a,如果是没有变量声明,如果直接a,则表示在全局变量中定义变量a;

2.如果引用函数内部的变量?

由1可知,JS中只存在函数作用域,那么我们如何才能在拿到函数中定义的变量呢?

根据JS的语法规则:内部函数(或者内部对象)中,可以访问外部函数中的变量。

什么意思呢?举例说明例1:

function abc(){
 var a=1;
 !function(){
 alert(a)
} ()
} //此时不会报错,a=1

再举一个例子(内部对象的例子)例2:

var o={
 a=1,
 myfun:function(){
 return this.a
}
}

则alert(o.myfun())得到的值为1,现在我们大概了解了如何访问函数(或者对象,其实函数的本身也是对象)中的变量!

3.什么是闭包?

我的理解就定义在一个函数内部的函数!

闭包是函数内部与外部之间的桥梁!

即内部函数在定义它的外部使用时,就创建了一个闭包!

我们知道,一般情况下,当函数被调用完,内存会被释放,但是应用于函数闭包比如

function abc1(){
 var a=1;
function abc2(){
 a++;
}
return abc2()
}

当我们调用abc1()函数后,因为abc1函数的中又调用了abc2()函数,因此函数abc1()中的变量在子函数中被调用,所以在父函数abc1()调用结束后

变量a的内存空间并不会被释放!

为什么GC机制无法回收abc1()函数中的变量a,  因为首先我们在全局中调用了函数abc1(),我们设全局对象为c,abc1()对象为b,同时我们在对象b

即函数abc1()中又调用了函数abc2(),设abc2(0为a。

再次理解这种关系    c中调用了b,b中又调用了a,JS中规定当a,b对象两两互相引用,并且a,b中又有一个被a,b函数之外的对象c引用时,GC机制不执行垃圾回收(变量清空)!

由此我们引出了闭包的重要作用:

如果内部函数在其外部被调用,则会产生闭包,闭包用于保存某些变量的值,不会被垃圾回收机制回收!

4.闭包的缺点

因为使用闭包后,某些变量会在函数调用之后持续的保持在内存中,因此滥用闭包会导致内存泄漏!

5.扩展应用,加深对于闭包的理解!

var o={
 a:1;
myfunc:function(){
return function(){
 return this.a;
}
}
alert(o.myfunc()()); // a is not defined
}

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数据结构与算法技巧总结》、《JavaScript数学运算用法总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》及《JavaScript遍历算法与技巧总结》

希望本文所述对大家JavaScript程序设计有所帮助。

(0)

相关推荐

  • javascript 闭包详解及简单实例应用

    JS 闭包详解及实例: 最近学习JS的基础知识,学习了闭包的知识点,有很多疑惑,这一段时间还是一直有在看闭包的相关知识理解就更深入了一点,下面说说我的理解. function fn(){ var a = 0; return function (){ return ++a; } } 如上所示,上面第一个return返回的就是一个闭包,那么本质上说闭包就是一个函数.那么返回这个函数有什么用呢? 那是因为这个函数可以调用到它外部的a这个变量.其实也就是说,return返回的是这个函数 + a这个变量

  • JavaScript中闭包的详解

    闭包是什么 在 JavaScript 中,闭包是一个让人很难弄懂的概念.ECMAScript 中给闭包的定义是:闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量. 是不是看完这个定义感觉更加懵逼了?别急,我们来分析一下. 闭包是一个函数 闭包可以使用在它外面定义的变量 闭包存在定义该变量的作用域中 好像有点清晰了,但是使用在它外面定义的变量是什么意思,我们先来看看变量作用域. 变量作用域 变量可分为全局变量和局部变量.全局变量的作用域就是全局性的,在 js

  • JavaScript 匿名函数(anonymous function)与闭包(closure)

    引入 匿名函数 闭包 变量作用域 函数外部访问函数内部的局部变量 用闭包实现私有成员 引入 闭包是用匿名函数来实现.闭包就是一个受到保护的变量空间,由内嵌函数生成."保护变量"的思想在几乎所有的编程语言中都能看到. 先看下 JavaScript 作用域: JavaScript 具有函数级的作用域.这意味着,不能在函数外部访问定义在函数内部的变量. JavaScript 的作用域又是词法性质的(lexically scoped).这意味着,函数运行在定义它的作用域中,而不是在调用它的作用

  • 一分钟理解js闭包

    什么是闭包? 先看一段代码: function a(){ var n = 0; function inc() { n++; console.log(n); } inc(); inc(); } a(); //控制台输出1,再输出2 简单吧.再来看一段代码: function a(){ var n = 0; this.inc = function () { n++; console.log(n); }; } var c = new a(); c.inc(); //控制台输出1 c.inc(); //

  • 详谈JavaScript的闭包及应用

    闭包真的是学过一遍又一遍,Js博大精深,每次学习都感觉有新的收获.相信在大家封装前端插件时,闭包是必不可少的.闭包的真正好处我个人认为除了封装还是封装,能带个我们私有方法,和调用上的灵活方便,也会使你的代码对外的对象保持干净整洁. 进入正题 维基百科这样定义了JS闭包:在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的

  • JavaScript利用闭包实现模块化

    利用闭包的强大威力,但从表面上看,它们似乎与回调无关.下面一起来研究其中最强大的一个:模块. function foo() { var something = "cool"; var another = [1, 2, 3]; function doSomething() { console.log( something ); } function doAnother() { console.log( another.join( " ! " ) ); } } 正如在这

  • 轻松学习Javascript闭包

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 当function里嵌套function时,内部的function可以访问外部function里的变量. function foo(x) { var tmp = 3; function bar(y) { alert(x + y + (++tmp)); } bar(10); } foo(2) 不管执行多少次,都会alert 16,因为bar能访问foo的参数x,也能访问foo的变量tmp. 但

  • javascript深入理解js闭包

    一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数

  • 前端开发必须知道的JS之闭包及应用

    在前端开发必须知道的JS之原型和继承一文中说过下面写篇闭包,加之最近越来越发现需要加强我的闭包应用能力,所以此文不能再拖了.本文讲的是函数闭包,不涉及对象闭包(如用with实现).如果你觉得我说的有偏差,欢迎拍砖,欢迎指教.一. 闭包的理论 首先必须了解以下几个概念: 执行环境 每调用一个函数时(执行函数时),系统会为该函数创建一个封闭的局部的运行环境,即该函数的执行环境.函数总是在自己的执行环境中执行,如读写局部变量.函数参数.运行内部逻辑.创建执行环境的过程包含了创建函数的作用域,函数也是在

  • javascript中闭包概念与用法深入理解

    本文实例分析了javascript中闭包概念与用法.分享给大家供大家参考,具体如下: 1.问题的引出,什么时候会遇到闭包? 首先因为JS是没有块状作用域的,但是有函数作用域即函数作为了局部变量之间的界限,不同函数内的局部变量具有独立性, 因为JS没有块状作用域,笔者初学JS时,在事件的监听时,因为不理解JS中局部变量的作用域,犯过不少错误! (1)JS中的变量作用域 for(var i=0;i<9;i++) { } alert(i) //输出9 我们发现,虽然变量i是块状区域for()内的一个局

  • 关于JavaScript中异步/等待的用法与理解

    昨天更新的是"JavaScript中的Promise使用详解",其实也就是说了下基本用法和自己对Promise的理解,可能有错误之处,也欢迎指出.今天就说一说"JavaScript中的async/await的用法和理解" JavaScript中异步/等待的用法和理解 编程语言中任意一个关键字都是有意义的,我们先从字面意思来理解. 1.async async 是"异步"的简写,带async关键字的函数,是声明异步函数,返回值是promise对象,如

  • javascript中的闭包概念与用法实践分析

    本文实例讲述了javascript中的闭包概念与用法.分享给大家供大家参考,具体如下: 闭包的概念:闭包是指有权访问另一个函数作用域中的变量的函数 (引自<javascript高级程序设计第三版>178页).闭包的优点是不会产生全局变量,避免变量污染问题,但是闭包也有一个缺点就是闭包携带包含它的函数作用域会比其它函数占用更多的内存,过度使用会导致内存占用过多. wiki上关于闭包的概念: In programming languages, closures (also lexical clos

  • JavaScript中闭包的写法和作用详解

    1.什么是闭包 闭包是有权访问另一个函数作用域的变量的函数. 简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内.而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数和声明的其他内部函数.当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包. 2.变量的作用域 要理解闭包,首先要理解变量的作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变

  • JavaScript函数节流概念与用法实例详解

    本文实例讲述了JavaScript函数节流概念与用法.分享给大家供大家参考,具体如下: 最近在做网页的时候有个需求,就是浏览器窗口改变的时候需要改一些页面元素大小,于是乎很自然的想到了window的resize事件,于是乎我是这么写的 <!DOCTYPE html> <html> <head> <title>Throttle</title> </head> <body> <script type="text

  • C#中闭包概念讲解

    理解C#中的闭包 1. 闭包的含义 首先闭包并不是针对某一特定语言的概念,而是一个通用的概念.除了在各个支持函数式编程的语言中,我们会接触到它.一些不支持函数式编程的语言中也能支持闭包(如java8之前的匿名内部类). 在看过的对于闭包的定义中,个人觉得比较清晰的是在<JavaScript高级程序设计>这本书中看到的.具体定义如下: 闭包是指有权访问另一个函数作用域中的变量的函数. 注意,闭包这个词本身指的是一种函数.而创建这种特殊函数的一种常见方式是在一个函数中创建另一个函数. 2. 在C#

  • JavaScript中闭包之浅析解读(必看篇)

    JavaScript中的闭包真心是一个老生常谈的问题了,最近面试也是一直问到,我自己的表述能力又不能完全支撑起来,真是抓狂.在回来的路上,我突然想到了一个很简单的事情,其实我们在做项目时候,其实就经常用到闭包的,可是面试问的时候,回答又往往是我们经常搜到的答案,唉 不管是应付面试 还是真的想学点东西 ,我也用自己的理解跟大家分享一下,书面化就避免不了了的. 1.闭包是什么? 红宝书中曰:"是指有权访问另外一个函数作用域中的变量的函数." 简单的说,JavaScript允许使用内部函数-

  • JavaScript中的标签语句用法分析

    本文实例分析了JavaScript中的标签语句用法.分享给大家供大家参考.具体分析如下: 最近在看w3school,然后看到js部分, <!DOCTYPE html> <html> <body> <script> cars=["BMW","Volvo","Saab","Ford"]; list: { document.write(cars[0] + "<br>

  • javascript中eval和with用法实例总结

    本文实例讲述了javascript中eval和with用法.分享给大家供大家参考,具体如下: 我们都知道javascript的作用域机制,但是with和eval有时会"破坏"我们对于作用域的常规理解.下面参考网上资源和自己理解总结一下eval和with的用法. 一.eval 1.eval函数:把一个字符串当作一个js表达式一样去执行它. 2.语法:eval(strScript) 注:参数strScript是必填项 3.使用说明 (1)它是有返回值的,如果参数字符串是一个表达式,就会返回

  • 有关JavaScript中call()和apply() 的一些理解

    call()方法和apply()方法,在上层应用中用的不是很多,但在底层写JS框架的时候却常常看到.然后度娘谷哥一番,也发现好多达人写出了自己的理解和笔记,但始终还是云里雾里,于是去W3C学习了下 在W3C网上研究这两个方法的时候,看到一个词语,叫"对象冒充",这个概念本人觉得还是挺重要的,让我对这两个方法理解起来更加直观. call()方法,看下官方给出的例子 function sayColor(sPrefix,sSuffix) { alert(sPrefix + this.colo

随机推荐