作用域
作用域与执行上下文的区别与联系
-
区别1
全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了。而不是在函数调用时。
全局执行上下文环境是在全局作用域确定之后,js代码马上执行之前创建。
函数执行上下文环境是在调用时,函数体代码执行之前创建。
-
区别2
作用域是静态的,只要函数定义好了就一直存在,且不会再变化
上下文环境是动态的,调用函数时创建,函数调用结束时上下文环境就会自动释放
-
联系
上下文环境(对象)是从属于所在的作用域
全局上下文环境==》全局作用域
函数上下文环境==》对应的函数作用域
作用域链
-
理解
多个上下级关系的作用域形成的链,它的方向是从下向上的(从内到外)
查找变量时就是沿着作用域链来查找的。
-
查找一个变量的查找规则
在当前作用域下的执行上下文中查找对应的属性,如果有直接返回,否则进入2。
在上一级作用域的执行上下文中查找对应的属性,如果有直接返回,否则进入3。
再次执行2的相同操作,直到全局作用域,如果还找不到就抛出找不到的异常。
如何产生闭包?
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包。
闭包到底是什么?
- 理解1:闭包是嵌套的内部函数
- 理解2:包含被引用变量(函数)的对象
- 使用Chrome调试查看
注意:闭包存在于嵌套的内部函数中。
产生闭包的条件?
函数嵌套
内部函数引用了外部函数的数据(变量/函数)
常见闭包
- 将函数作为另一个函数的返回值
- 将函数作为实参传递给另一个函数调用
闭包的作用
- 使用函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
- 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
问题1:函数执行完以后,函数内部声明的局部变量是否还存在?
一般不存在,存在于闭包的变量才可能存在
问题2:在函数外部能直接访问函数内部的局部变量吗?
不能,但是可以通过闭包让外部操作它
闭包的生命周期
- **产生:**在嵌套内部函数定义执行完时就产生了(不是在调用)
- **死亡:**在嵌套的内部函数称为垃圾对象时
闭包的应用
定义JS模块
- 具有特定功能的js文件
- 将所有的数据和功能都封装在一个函数内部(私有的)
- 只向外暴露一个包括n个方法的对象或者函数
- 模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能
闭包的缺点和解决方案
内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时,就会抛出内存溢出的错误
内存泄露
-
占用的内存没有及时释放
-
内存泄露积累多了就容易导致内存溢出
-
常见的内存溢出
意外的全局变量
没有及时清理的计时器或回调函数
闭包
每日一句
做前,可以环视四周;做时,你只能或者最好沿着以脚为起点的射线向前。
转载:https://blog.csdn.net/czzyw/article/details/116497884
查看评论