JavaScript中的闭包与作用域 、作用域链是什么?
JavaScript中作用,作用域链和闭包详解
一、作用域
在js中有全局变量和局部变量之分:
比如
var a = 1;
function sum(){
var b=1
console.log(b) //1
console.log(a) //2
}
sum()
console.log(a) //3
console.log(b) //4
例子中 a 是全局变量,b是局部变量(定义在函数内部,只能在函数内部访问)所以第1行正确
函数内部也能访问全局变量 a所以第2行也能正确 第三行也正确。第4行有外部不能访问
内部变量。变量声明的时候初始化,局部变量在函数调用完时候销毁,全局变量在页面关闭时候销毁
(注意如何b没有用var修饰,就默认是全局变量)
二、js函数
1、function 函数名(){
}
2、匿名函数 function(){}
3、立即执行函数又名表达式函数
(function(i){
//dosometing
})(i)
4、私有函数
function a(){
function b(){ ====私有函数
}
}
5、var 发=new Function(//dosomething)
6、变量的提升 函数提升
函数的生命周期
1、在函数创建阶段,JS解析引擎进行预解析,会将函数声明提前,同时将该函数放到全局作用域中(js中函数是一等公民优先考虑)或当前函数的上一级函数的局部作用域中。
在函数
执行阶段,会创建该函数的执行上下文并且JS引擎会将当前函数的局部变量和内部函数进行声明提前,然后再执行业务代码,当函数执行完退出时,释放该函数的执行上下文,并注销该函数
的局部变量。
2、函数声明大于变量声明()
三、作用域链
1、在JS中运行中 当某个函数第一次被调用时 ,就会创建一个执行环境(execution context)以及相应的作用域链在js中将声明的变量、参数、私有函数封装在一个结构体内 ,对外界来
说不可见的 并把作用域链赋值给一个特殊的内部属性([scope])。然后使用this.arguments(arguments在全局环境中不存在)和其他命名参数的值来初始化函数的活动对象(activation
object)。当前执行环境的变量对象始终在作用域链的第0位
例子
function a(){
var a;
function b(){
return a
}
return b
}
var fun=a()
fun()
在JS运行上面机制 a函数作用链(scope chain ) b作用域链(b是内部函数)[scope chain] 会生成执行上下文变量 当代码在一个环境中执行时,会创建变量对象的一个作用域
链。作用域链的用途是保证对执行环境(执行上下文)有权访问的所有变量和函数的有序访问。
变量对象(VO):变量对象即包含变量的对象,变量对象我们无法访问,除此之外和普通对象没什么区别。变量对象存储了在上下文中定义的变量和函数声明
活动对象(AO):是在进入函数执行
环境时刻被创建的,它通过函数的 arguments 属性初始化。
变量对象和活动对象的关系
未进入执行阶段之前,变量对象(VO)中的属性都不能访问,只是声明但是进入执行阶段
之后,变量对象(VO)转变为了
活动对象(AO),里面的属性都能被访问了,然后开始进行执行阶段的操作。它们其实都是同一个对象,只是处于执行环境的不同生命周期。AO 实际上是包含了 VO 的。因为除了 VO 之外,AO
还包含函数的 parameters,以及 arguments 这个特殊对象。也就是说 AO 的确是在进入到执行阶段的时候被激活,但是激活的除了 VO 之外,还包括函数执行时传入的参数
和 arguments 这个特殊对象。
四、 JavaScript闭包
在js私有函数对外部函数产生引用或者变量依赖就会产生闭包 通俗的讲函数是可以嵌套函数的,内部function可以访问外部function的变量;通过引用访问函数内的函数,实现内存的
保留;访问函数内的函数,突破变量作用域限制
var a=function(){ var a的变量 function b(){ a++; } return b
}
var s=a()
1、信息保留就是引用存在,空间不会因为函数(内部函数)销毁,而消失,
c.add1();