一.Js作用域
-
案列
var a=10; function bar(){ alert(a); }; function foo(){ var a=20; bar(); } foo();
-
js作用域:
- 全局作用域:整个script标签或者是一个单独的js文件
- 局部作用域:函数的内部起作用
-
全局变量:全局作用域下定义的变量
局部变量:在函数内部的变量
全局变量只有在浏览器关闭才能被销毁,占内存
局部变量在function执行完毕后就销毁,节省内存 -
js的块级作用域
if(){var num=10 }
大括号可以调用
若定义为if(){const/let num=10 }
形成块级作用域 -
匿名函数形成当前作用域
-
形式
(function bar(){} ()) 、(function bar() {} ) () 定义其中变量不影响外部
-
-
问题
var b=3 (function(){b=5;var b=2 })(); console.log(b)
二.闭包
-
案列
function car(){ var speed = 0 function fn(){ speed++ console.log(speed) } return fn } var speedUp = car() speedUp() speedUp()
函数作为参数被传递,函数作为返回值被返回
-
定义
- 有权访问另一函数作用域中变量的函数,它延伸了变量的使用范围
- 访问函数内部变量、内部变量不会被外部改变; 保持函数在环境中一直存在,不会被垃圾回收机制处理
-
闭包原理
-
js开始执行后,在堆内存中创建执行环境栈,存放不同的执行上下文(Execution Context)
-
基本数据类型直接存放在栈中,访问的速度更快,而引用类型在堆中
-
只要函数被调用就重新开辟一个执行上下文,执行上下文中先定义以下步骤
-
先确定this指向
-
初始化作用域链
-
定义变量对象
-
函数创建时候就有[[scope]]
-
根据该函数中是否有变量被引用,决定是否销毁
-
闭包:因为函数被引用,EC执行上下文不能被释放,就往下压
备注 VO(Variable Object):全局作用域变量 AO:局部作用域变量 主线程回收EC执行环境栈中内存,而GC回收堆中垃圾
-