ES5关于闭包/作用域的理解

作用域

理解:
  • 就是一块"地盘",,一个代码所在的区域
  • 它是静态的(相对于上下文对象),在编写代码时就确定了
分类:
  • 全局作用域
  • 函数作用域
  • ES5没有块作用域(ES6有了)
作用
  • 隔离变量,不同作用域下同名变量不会有冲突
举例
if(true){
    var c = 3;
  }
console.log(c); //3

上面之所以可以打印出c的原因是因为ES5没有块作用域,但是如果在Java语言当中,c的值是取不到的。

如何判断作用域的个数

在这里插入图片描述

  • 我们看到,上面代码中,我定义了两个function,分别有各自的作用域,加上全局作用域之后共有三个作用域。由此,我们得到:
  • 作用域N = F(n) + 1; ------------函数的个数加一

作用域的作用

var a = 10;
  function fn1() {
    var b = 20;
   function fn2() {
     var c = 4;
     console.log(a); //10
     console.log(b); //20
     console.log(c); //4
     console.log(d); //d is not defined
   }
  }
  • 我们发现 abc是可以正常打印的,而d是未定义。
  • 提及作用域链的概念:作用域链就是由多个上下级关系的作用域组成的链
  • 作用:
  • 查找变量时是沿着作用域链查找的,并且遵循就近原则(就近原则:假如fn1中含有变量a,且值为100,则打印出a的值是100),查找过程的终止,是查找到了作用域链的顶层,即全局作用域。

作用域与执行上下文的区别

区别1
  • 除全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经创建了,而不是在函数调用时。
  • 全局执行上下文环境是在全局作用域确定之后,JS代码马上执行之前创建
  • 函数执行上下文是在调用函数时,函数体代码执行前创建。
区别2
  • 作用域是静态的,只要函数定义好了就一直存在,且不在变化。
  • 执行上下文是动态的,调用函数时创建,函数掉用结束时上下文环境就会被释放。
联系
  • 上下文环境(对象)属于所在的作用域
  • 全局上下文环境===》全局作用域
  • 函数上下文环境===》对应的函数作用域

闭包

  • ES5的两大神兽之一哈,(网上解析很多,这里作为自己的笔记)下面深入了解下,什么是闭包。
  • 看如下示例
var scope = "global scope";
  function checkscope(){
    var scope = "local scope";
    function f(){
      return scope;
    }
    return f;
  }

  var foo = checkscope();
  foo();
  • 将上面代码在谷歌中调试,return f 语句进行断点,查看参数。
    在这里插入图片描述
  • 由上图可知,形成了闭包对象,包含参数scope。
闭包的产生

1、当一个嵌套的内部(子)函数调用了嵌套的外部函数(父)的变量时,就会产生闭包。
2、闭包:嵌套的内部函数。包含被引入变量(函数)的对象,可以理解为对象

  • 上图中的scope参数是全局变量,由此重新理解下闭包的定义:
    在《JavaScript权威指南》中就讲到:从技术的角度讲,所有的JavaScript函数都是闭包。
  • 示例2
function showDelay(msg, time) {
    setTimeout(function () {
      alert(msg);
    },time);
  }
  showDelay('aaa',1000);
  • 上面闭包对象只有一个变量msg,因为只有msg变量被引用。、
  • 示例3
function fn1() {
    var a = 2;
    function fn2() {
      a++;
      console.log(a);
    }
    return fn2;
  }
  var f = fn1();
  f(); //3
  f(); //4
  • 上面示例演示了将函数作为另一个函数的返回值,之所以可以打印出3,4,是因为a作为闭包函数对象的参数一直存在,并没有消失。(其根本原因是var f = fn1();被 f 引用着)
  • 看到这里不由发出三个疑问:
  • 函数执行完后,函数内部声明的局部变量是否还存在? 答:一般情况下不会存在,只有出现闭包对象时才可能存在。
  • 那么示例3中怎样使闭包对象消失呢?答案是:f = null;
  • 在函数外部能直接访问函数内部的局部变量嘛? 答:不能
闭包的作用
  • 与作用域链相反,闭包是一种由外向内访问变量的技术。
闭包的生命周期
  • 产生:在嵌套内部函数定义执行完成时就产生了(不是在调用时)
  • 死亡:在嵌套的外部函数变成垃圾对象时消失
闭包的缺点
  • 当被其他变量引用时,闭包不会消失,所以如果大量使用闭包时,可能会造成内存溢出或者内存泄漏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值