作用域定义了在当前上下文中能够被访问到的成员,在Javascript中分为全局作用域和函数作用域,通过函数嵌套可以实现嵌套作用域。 闭包一般发生在嵌套作用域中。闭包是JavaScript最强大的特性之一,很多高级应用都要依靠闭包实现。如OO的私有成员和模块化等。然而闭包虽然强大,但一般比较占用内存另外如果使用不当还会引起内存泄露,对闭包有了解的jser一般都知道闭包的这些个问题,本文先阐述了闭包和作用域链的关系,然后分析了产生这些个问题的原因。下面是一段闭包的示例代码:

var  name = "windows's name";
var object = {
    name : "object's name",
    getNameFunc:function(){
        var that = this;
        return function(){
            return that.name;
        }
    }
};
console.log(object.getNameFunc()());

    当javascript代码执行时会创建一个执行上下文对象,执行上下文对象包含一个作用域链,作用域链有一个或多个变量对象组成,作用域链中保存的是对变量对象的引用。变量对象定义了在当前作用域中声明的变量和函数。在代码的执行过程中JAVASCRIPT引擎会按照自上而下的顺序检索作用链中的变量对象的成员来解析需要被访问(读或写)的变量或函数,在检索过程中如果在作用域链的某个变量对中象查找到与之匹配的标识符就会终止检索。通过这种方式当在代码中如果有同名的变量就可以区分出来我们要操作那个变量。
    当代码载入完成后 Javascript引擎会创建一个全局的执行上下文,全局执行上下文的作用域链只包含一个全局变量对象。Javascript的函数对象拥有一个私有的socpe属性,当函数被创建时会使用当前的作用域链初始化函数scope属性。当函数被执行时会创建函数的执行上下文对象和当前作用域的变量对象,创建函数的执行上下文对象时先使用函数的scope属性给执行上下文对象的作用域链赋值,再把创建的变量对象放入作用域链的顶端来初始化执行上下文的作用域链。位于作用域链顶端的变量对象也称为活动对象。默认情况下当函数返回时会销毁它的活动对象和作用域链,这也是为什么我们函数的外部不能够访问到在函数内部定义的成员。然而在发生闭包的情况下,当内部函数被创建时,内部函数的scope属性指向包含它的外部函数的作用域链。这时内部函数引用了外部函数的活动对象,当外部函数返回时,它的活动对象没有被释放,直到引用它的内部函数被销毁时才会释放外层函数的活动对象。所以它所包含的内部函数仍然可以访问在外部函数中定义的成员,另外这也是闭包比较占用内存的原因。
    内存泄露问题是由于部分浏览器使用引用计数来作为垃圾回收机制,当在我们的代码中发生了循环引用时,就会造成资源不能被回收从而引起内存泄露。发生内存泄露有时是因为在我们的代码中发生了明显的循环引用,有时则不那么明显。对于前者一般通过仔细检查代码就能发现问题所在,对于后者就需要我们对闭包有足够的了解才能发现。如下面代码:

function outerFunc(){
    var obj = document.getElementById("element");
    obj.onclick=function innerFunc(){
        alert("Hi! I will leak");
    };
    obj.bigString=new Array(1000).join(new Array(3000).join("XXXXX"));
    // This is used to make the leak significant
};

    在上面这段代码中,外部函数outerFunc中的局部变量obj引用文档中ID为element的Dom元素,obj.onclick指向内部函数innerFunc的引用,内部函数innerFunc的scope属性指向的作用链中包含外部函数outerFunc的活动对象的引用,活动对象的obj成员再次指向文档中ID为element的Dom元素从而构成了循环引用。

Javascript中闭包的作用域链的更多相关文章

  1. javascript中闭包与作用域的理解

    很多js的框架与插件编写都用到了闭包,所以,阅读和掌握闭包很有必要.最近学习vue框架时,经常会猜想很多功能的native js实现,很多都应用到了闭包,闭包除了目前已知的一些特性,如:可以保持局部变 ...

  2. javascript 执行环境,作用域链和闭包

    首先看下这条语句: (function($) {…})(jQuery): 1.原理: function(arg){…}这就定义了一个匿名函数,参数为arg 而调用函数时,是在函数后面写上括号和实参的, ...

  3. 浅谈JavaScript中闭包

    引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...

  4. [ JS 进阶 ] 闭包,作用域链,垃圾回收,内存泄露

    原网址:https://segmentfault.com/a/1190000002778015 1. 什么是闭包? 来看一些关于闭包的定义: 闭包是指有权访问另一个函数作用域中变量的函数 --< ...

  5. JS闭包、作用域链、垃圾回收、内存泄露相关知识小结

    补充: 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变 ...

  6. 在JavaScript中闭包的作用和简单的用法

    在JavaScript中闭包的作用和简单的用法 一.闭包的简介 作用域链:在js中只有函数有作用域的概念,由于函数内能访问函数外部的数据,而函数外部不能访问函数内部的数据,由上述形成一种作用域访问的链 ...

  7. 在Javascript中闭包(Closure)

    在Javascript中闭包(Closure) 什么是闭包 “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. ...

  8. javascript中闭包最简单的简绍

    javascript中闭包是什么 JavaScript 变量可以是局部变量或全局变量.私有变量可以用到闭包.闭包就是将函数内部和函数外部连接起来的一座桥梁. 函数的闭包使用场景:比如我们想要一个函数来 ...

  9. javascript中的this作用域详解

    javascript中的this作用域详解 Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大.在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉 ...

随机推荐

  1. STL中map,set的基本用法示例

    本文主要是使用了STL中德map和set两个容器,使用了它们本身的一些功能函数(包括迭代器),介绍了它们的基本使用方式,是一个使用熟悉的过程. map的基本使用: #include "std ...

  2. git 远程分支创建与推送

    git 远程分支创建与推送   原文地址:http://hi.baidu.com/lingzhixu/blog/item/4a9b830bb08a329fe850cd5b.html 本地分支的创建 本 ...

  3. 不用position,让div垂直居中

    先弄懂after伪类的用法,就可以很容易理解了. <!DOCTYPE html> <html lang="en"><head> <meta ...

  4. javascript 之 this 用法

    参考视频:http://www.imooc.com/video/6430 JavaScript中的this比较灵活,也是让很多初学者摸不到头脑,那么根据在不同的环境下,在同一个函数,不同的调用方式下, ...

  5. App签名--- Android

    步骤: 下面就Next即可

  6. hbase权威指南学习笔记--过滤器

    1.使用hbase是shell客户端进行过滤查询 scan 'testtable',{COLUMNS=>'colfam1:col-0',FILTER=>RowFilter.new(Comp ...

  7. oc基础 不可变字符串的创建和使用

    oc基础  不可变字符串的创建和使用 简介:下面都是字符串基本用法. 1.字符串的创建 //创建oc常量字符串 NSString *str=@"hello world!"; NSL ...

  8. UIScrollView 代理方法

    在使用UIScrollView和它的子类UITableView时,有时需要在不同操作状态下,做不同的响应. 如何截获这些状态,如正在滚动,滚动停止等,使用UIScrollViewDelegate_Pr ...

  9. IE 与 FireFox 的 event 详解 (转)

    原文链接 FF的FIREBUG,不仅能测试JS还能检查CSS错误,是一般常用的. 但它主要检查FF方面的错误,对IE就无能为力了. 要测试IE,就用ieTester,它可以测试IE几乎所有版本(1.0 ...

  10. [Head First Python]6. 定制数据对象:打包代码与数据

    相同功能,演进实现 数据文件 sarah2.txt sarah Sweeney,2002-6-17,2:58,2.58,2:39,2-25,2-55,2:54,2.18,2:55,2:55 1- 返回 ...