闭包(1)初识闭包

来源:互联网 发布:ntfs for mac序列号 编辑:程序博客网 时间:2024/05/29 17:18

一、初识闭包

          起初,我对闭包的理解简单粗暴:函数里嵌套的函数就是**闭包**!且内部函数可以访问外部函数的变量,外部函数却无法探知内部的函数变量。          类似Java里被private修饰的类。且闭包也可以设置私有成员,但是关系到内存、垃圾回收却是没什么好比较的。 **闭包**的正经定义是:把有权访问另一函数作用域的变量的函数称为**闭包**。   ECMAScript中提到**闭包**:     1.即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从外部函数中返回)。换句话说:内部函数在外部函数返回后被执行了。     2.在代码中引用了自由变量。------这里都有关系到**作用域链**和**垃圾回收机制**(*下文会提到*),这种机制也使得闭包能够保存数据。

二、关于作用域

   JavaScript不像其他C、Java那种块级作用域,JavaScript只有函数作用域。像if(){}或者for(){},这样带花括号的语句是没有用的。

如下:

<script>if(1){    var noway = "这个花括号关不住我哈哈哈";}    console.log(noway);</script>

控制台输出

了解作用域之后我们应该要认识作用域链了,这关系到函数之间的访问机制。

  functon a(){           var n = 1;            function b(){          var m  =2;   }} 

这里的作用域链是这样

   在这里内部函数的作用域可以通过**作用域链**来访问所有的外部作用域中的变量和函数,作用域链把这些作用域串起来,   这样每个作用域都可以向上搜索、访问。不可向下。这也是**闭包**存在的关键所在。作用域链本质是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。

三、闭包的作用

  **1、读取函数内部的变量**(可以设置私有变量,可像Java一样写 set()、get()方法)

例:

function Tree(name){    this.get = function(){        return name;        };    this.set = function(value){        name = value;        };      }    var tree = new Tree("apple");//apple    console.log(tree.get());    tree.set("pear");    console.log(tree.get());//pear

这里写图片描述

        this.set = function(name){        this.name = name;        }//并不可以像Java一样写

2、让某些变量的值保存在内存中不被回收,实现数据共享。

    在JavaScript中,在函数声明里的函数都是局部的,函数运行完后就会被释放掉。    但是如果这个作用域依旧在被引用(与全局变量有关联,或是说作用域链依旧存在),那函数就会被留在内存。    细节可以看看JavaScript的**垃圾回收机制**。
var a = function (){  var n = 0;  return function () {   console.log(n++);}var o = a();//赋值给了全局变量,var 也可去掉 console.log(a()); o();//0 o();//1 o();//2   a()();//0 a()();//0 a()();//0

这里写图片描述
ps:(1)关于为什么var可以去掉,是因为使用var声明的变量会被添加到最近的作用域中,如上o加入到了全局环境。(2)如果初始化变量时没有使用var来声明, 那么该变量会被自动加到全局环境中。

推荐书籍:《JavaScript高级语言程序设计》 《JavaScript权威指南》

推荐博客 :http://web.jobbole.com/84328/
《大部分人都会做错的经典JS闭包面试题》
可以作为学习成果的检验


望多指正,文章也会不断修改扩充。

0 0
原创粉丝点击