作用域、作用域链、闭包

作用域、作用域链

一、Js以前没有块级作用域,不过在ES6中有let了。

二、Js使用函数作用域

function aaa(){
        var a = "a";
    }
    console.log(a);//报错

三、声明提前

console.log(aaa)//报错
console.log(aaa);//undefined 声明未定义
var aaa;
console.log(aaa); //undefined 声明未定义
var aaa = "aaa";

四、Js的作用域链

function Fun(){
    var aaa = "aaa",
         fun = "fun";
    function Inter(){
        var aaa = "ccc";
        console.log(aaa); //ccc
        console.log(fun); //fun
    }
    Inter();
}
Fun();

Inter的作用域链

找到就停止查找返回数据,找不到就延作用域链查找,直到Global也查不到就返回报错;

五、Js的作用域链在执行前已经被创建

闭包

一、闭包:是指有权访问另一个函数作用域中的变量的函数;

二、闭包的特点:局部变量不会被垃圾回收;

//定义一个函数时,实际是保存它的作用域链。当调用这个函数时,会创建一个新的对象来保存局部变量,并且把这个新的对象添加到作用域链上。当函数返回时,将作用域链中的这个对象删除。

//如果这个函数定义了嵌套函数,并将它作为返回值返回或者存储在某处的属性里,就会有一个外部的引用指向这个嵌套函数。

三、上面那句是书上的话,不好理解。我翻译下就是父函数内创建的变量,子函数调用。只要子函数没有被销毁,父函数和创建的变量就不会被销毁。

举个栗子

function counter(){
        var a = 0;
        function rest(){
            console.log(a++);
        }
        return rest;
    }
    var scope = counter();
    scope();//0
    scope();//1
    scope();//2

创建闭包的常见方式,就是在一个函数内部创建另一个函数,外部函数将内部函数作为返回值返回。有的时候这个外部是全局。

for(var i = 0;i<elements.length;i++){
        elements[i].onclick = function(){
            console.log(i);  //elements.length
        }
    }

上面每次点击,输出的都是elements.length。因为onclick是一个点击的函数,不能被销毁,所以i也不能被销毁保存在Global中。所以点击输出的是elements.length。

for(var i = 0;i<elements.length;i++){
        function F(n){
            elements[n].onclick = function(){
                console.log(n);
            }
        }
        F(i);
    }

这样修改下就可以了。

四、垃圾回收机制:如果一个对象不再被引用,这个对象会被GC回收。如果两个对象相互引用,这两个都会被回收。如果a被b引用,b又被c引用,就不会被回收,就是闭包第一个例子的原因。

五、闭包的两种写法

function counter(){
        var a = 0;
        function rest(){debugger
            return a;
        }
        return rest();
    }
    counter();

定义调用在同一作用域

    function counter(){
        var a = 0;
        function rest(){debugger
            return a;
        }
        return rest;
    }
    //counter()();
    var scopt = counter();
    scopt();

定义调用不在同一作用域

时间: 2024-12-28 08:37:37

作用域、作用域链、闭包的相关文章

作用域 作用域链 闭包 思想 JS/C++比较

首先,我说的比较是指JS中这种思想/实现方式与C++编译原理中思想/实现方式的比较 参考链接:(比较易懂的介绍,我主要写个人理解) 作用域链: http://www.cnblogs.com/dolphinX/p/3280876.html 闭包:http://kb.cnblogs.com/page/110782/ 个人理解: 作用域链: 在JS中,function也是一种object的实例. 作用域的概念必须已经知晓. 作用域链:用于标识符解析:确定数据的存储位置以及数据作用域(数据访问).(应该

JavaScript this 局部变量全局变量 作用域 作用域链 闭包

从阮老师博客的一道测试题说起: 代码段一: var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); 代码段二: var name = "The Window"; var object

什么是作用域, 什么事闭包, 什么事原型链

什么是作用域 作用域即作用范围,在js中采用的是词法作用域,所谓的词法作用域之的是在代码编写的过程中体现出来的作用范围,代码一旦写好,不用执行作用范围就已经决定了,这个就是词法作用域 在js中作用域的规则, * 函数运行访问函数外的数据 * 在整个代码中只有函数可以限定作用域 * 首先需要考虑提升规则 * 如果当前作用域中已经有名字,就不再考虑函数外的名字(就近原则) # 作用域链 1. 在js中只有函数可以制造作用域,只要有代码就会有一个作用域即全局作用域,凡是代码中有函数那么这个函数就构成了

Javascript 进阶 作用域 作用域链

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/25076713 一直觉得Js很强大,由于长期不写js代码,最近刚好温故温故. 1.Javascript没有代码块作用域的概念,局部作用域是针对函数来说的. function fun() { for( var i = 0 ; i < 10 ; i++) {} //如果在Java中i此时应当属于未声明的变量,但是Js中i的作用域依然存在 console.log(i);//10 if(

理解js中的作用域以及初探闭包

前言 对于js中的闭包,无论是老司机还是小白,我想,见得不能再多了,然而有时三言两语却很难说得明白,反正在我初学时是这样的,脑子里虽有概念,但是却道不出个所以然来,在面试中经常会被用来吊自己的胃口,考察基础,虽然网上自己也看过不少相关闭包的文章,帖子,但貌似这玩意,越看越复杂,满满逼格高,生涉难懂的专业词汇常常把自己带到沟里去了,越看越迷糊,其实终归结底,用杨绛先生的一句话就是:"你的问题在于代码写得太少,书读得不够多",其实在我看来前者是主要的,是后者的检验, 自知目标搬砖20年(还

执行环境 作用域 作用域链 闭包的理解

1.首先 当一个变量或者函数被声明的时候 它的执行环境便被确认 , 执行环境定义了变量和函数有权访问的其他数据,决定了他们各自的行为, 而作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期 每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链.作用域链是函数被创建的作用域中对象的集合.作用域链可以保证对执行环境有权访问的所有变量和函数的有序访问. 作用域链的最前端始终是当前执行的代码所在环境的变量对象(如果该环境是函数,则将其活动对象作为变量对象),下一个变量对象

变量对象+作用域链+闭包

下文根据汤姆大叔的深入javascript系列文章删改,如果想深入理解请阅读汤姆大叔的系列文章.http://www.cnblogs.com/TomXu/... 变量对象 初步介绍 变量对象(缩写为VO)是一个与执行上下文相关的特殊对象,它存储着在上下文中声明的以下内容: 变量 (var, 变量声明); 函数声明 (FunctionDeclaration, 缩写为FD); 函数的形参 我们可以用普通的ECMAScript对象来表示一个变量对象: VO = {}; VO是执行上下文的属性(prop

javascript-词法作用域规则-作用域链-闭包运用学习心得

虽然在平时貌似,很习以为常的一些用法但是真要弄清这几个概念的时候,确实费了很大功夫,现在虽然不能说明白但总算有了一些心得.好吧下面直接开始 注本文(*)为相关链接 例子1.1 词法作用域规则:函数的嵌套关系是定义时决定的,而非调用时决定的,即词法作用域,即嵌套关系是由词法分析时确定的,而运行时决定. (*)http://blog.csdn.net/zzulp/article/details/8144520 (*)http://www.cnblogs.com/lhb25/archive/2011/

函数1、基本函数 2、作用域 3、闭包 4、面向对象

1.基本函数 JavaScript中函数基本上可以分为一下三类: 1 // 普通函数 2     function func(arg){ 3         return true; 4     } 5            6 // 匿名函数 7     var func = function(arg){ 8         return "tony"; 9     } 10    11 // 自执行函数 12     (function(arg){ 13         conso

(转载)Javascript 进阶 作用域 作用域链

载请标明出处:http://blog.csdn.net/lmj623565791/article/details/25076713 一直觉得Js很强大,由于长期不写js代码,最近刚好温故温故. 1.Javascript没有代码块作用域的概念,局部作用域是针对函数来说的. [javascript] view plaincopy function fun() { for( var i = 0 ; i < 10 ; i++) {} //如果在Java中i此时应当属于未声明的变量,但是Js中i的作用域依