JavaScript学习手册(56)

作用域

  1. 理解

    一块地盘,一个代码段所在区域

    它是静态的(相对于上下文对象),在编写代码时就确定了

  2. 分类

    全局作用域

    函数作用域

    没有块作用域(ES6有)

  3. 作用

    隔离变量,不同作用域下同名变量不会有冲突

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

  1. 区别1

    全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了。而不是在函数调用时。

    全局执行上下文环境是在全局作用域确定之后,js代码马上执行之前创建。

    函数执行上下文环境是在调用时,函数体代码执行之前创建。

  2. 区别2

    作用域是静态的,只要函数定义好了就一直存在,且不会再变化

    上下文环境是动态的,调用函数时创建,函数调用结束时上下文环境就会自动释放

  3. 联系

    上下文环境(对象)是从属于所在的作用域

    全局上下文环境==》全局作用域

    函数上下文环境==》对应的函数作用域

作用域链

  1. 理解

    多个上下级关系的作用域形成的链,它的方向是从下向上的(从内到外)

    查找变量时就是沿着作用域链来查找的。

  2. 查找一个变量的查找规则

    在当前作用域下的执行上下文中查找对应的属性,如果有直接返回,否则进入2。

    在上一级作用域的执行上下文中查找对应的属性,如果有直接返回,否则进入3。

    再次执行2的相同操作,直到全局作用域,如果还找不到就抛出找不到的异常。

如何产生闭包?

当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包。

闭包到底是什么?

  • 理解1:闭包是嵌套的内部函数
  • 理解2:包含被引用变量(函数)的对象
  • 使用Chrome调试查看

注意:闭包存在于嵌套的内部函数中。

产生闭包的条件?

函数嵌套

内部函数引用了外部函数的数据(变量/函数)

常见闭包

  1. 将函数作为另一个函数的返回值
  2. 将函数作为实参传递给另一个函数调用

闭包的作用

  • 使用函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
  • 让函数外部可以操作(读写)到函数内部的数据(变量/函数)

问题1:函数执行完以后,函数内部声明的局部变量是否还存在?

一般不存在,存在于闭包的变量才可能存在

问题2:在函数外部能直接访问函数内部的局部变量吗?

不能,但是可以通过闭包让外部操作它

闭包的生命周期

  1. **产生:**在嵌套内部函数定义执行完时就产生了(不是在调用)
  2. **死亡:**在嵌套的内部函数称为垃圾对象时

闭包的应用

定义JS模块

  1. 具有特定功能的js文件
  2. 将所有的数据和功能都封装在一个函数内部(私有的)
  3. 只向外暴露一个包括n个方法的对象或者函数
  4. 模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能

闭包的缺点和解决方案

  • 缺点

    函数执行完后,函数内的局部变量没有释放,占用内存时间会变长

    容易造成内存泄露

  • 解决

    能不用闭包就不用

    及时释放

内存溢出

  1. 一种程序运行出现的错误
  2. 当程序运行需要的内存超过了剩余的内存时,就会抛出内存溢出的错误

内存泄露

  1. 占用的内存没有及时释放

  2. 内存泄露积累多了就容易导致内存溢出

  3. 常见的内存溢出

    意外的全局变量

    没有及时清理的计时器或回调函数

    闭包

JavaScript学习手册(56)_第1张图片
每日一句
做前,可以环视四周;做时,你只能或者最好沿着以脚为起点的射线向前。

你可能感兴趣的:(橘子太酸辣,JavaScript学习手册,笔记,javascript,webkit,前端)