js作用域和闭包的知识

每个函数在定义的时候(或者说被创建的时候),都会初始化一个[[scope]]的属性,他指向这个函数除了函数自身之外所能访问的作用域,如代码

<script>

var a=0;

function x(){

var b=1;

}

x()

</script>

浏览器拿到这段代码的时候,js引擎会先进行变量的处理,在全部变量的作用域中,变量对象的值等于{a:undefined,x:function(){}},而此时也会给函数x的作用域[[scope]]属性进行初始化,他的值就等于window的变量对象{a:undefined,x:function(){}},当函数x执行的时候,js引擎会生成一个执行上下文,并且对应一个变量对象或者叫活动对象的东西,这个对象的包括函数的形参和局部变量arguments和this的值,并且把这个对象插入到函数x的作用域链的最前面。然后执行x,执行完x后,刚才生成的执行上下文和活动对象就会被销毁。但是scope属性是不会被销毁的。scope是当函数被销毁的时候才会被销毁。

<script>

var a=0;

function x(){

var b=1;

function inner(){

console.log(b)

}

return inner

}

var fun=x();

fun()

</script>

浏览器拿到这段代码的时候,前面的执行过程和上面说的是一样的,一开始的时候js引擎只是解析了函数x和初始化他的scope,inner还没有被定义,当执行x的时候,js引擎会定义inner函数,并且初始化他的作用域属性scope,他的值是类似一个指针数组,第一个元素指向父级函数x的变量对象,第二个元素指向window的变量对象,然后x函数的执行结果是返回inner函数的地址,如果没有这一句,那么x的变量对象是会被释放的,而且inner函数也会被销毁,所以他的scope也会被效果。但是如果x函数返回了inner函数,就意味着还有东西引用着inner函数,所以inner函数不能被销毁,并且它的scope也不会被销毁,而scope引用了x的变量对象,也就是说,x的变量对象也不能被销毁(执行x函数时生成了x函数的变量对象,x的scope有一项是指向这个变量对象的,x执行完之后,x的scope的指针就不会指向这个变量对象了),所以当fun执行的时候,console.log(b)的结果是1,也就是执行x是时候,生成的那个变量对象里b的值。这就是闭包的原理和作用域之间的关系。


js和c语言这种不一样,c语言的函数执行时,变量是在栈上面开辟空间进行存储的,函数执行完之后,变量就会被释放(malloc申请的从除外,因为那是在堆上面开辟的空间),但是js不是,js是用垃圾回收机制就行变量管理的,在函数里定义的变量是存在一个变量对象里的,函数执行完不代表他就会被释放,而一般的函数执行完后变量会被释放,是因为已经没有什么东西引用他了。而闭包就是利用了函数执行完,还指向某个变量对象实现的,如果某个函数里定义了很多占空间的变量,但是闭包只需要引用某一个小的变量,那个整个变量对象也不会被释放,所以这个时候,是很浪费空间的。所以闭包是由代价的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值