其他分享
首页 > 其他分享> > 6-作用域与作用域链、闭包基础

6-作用域与作用域链、闭包基础

作者:互联网

(一)、作用域与作用域链

了解AO和 GO 是为了解决js当中的一系列关于作用域和作用域链相关所产生的一切问题

function test(a,b){
 
}
  console.log(test.name);  //test
  console.log(test.length); //2
 //可以看出function也有属性,其实函数也是一种对象类型,也是一种引用类型,也是一种引用值

对象中有些属性我们是无法访问的,这些属性就是JS引擎内部固有的隐式属性

既然我们用不了,为什么我们需要去研究这些隐式属性?

因为如果不研究的话就不知道它的原理,在上层就没法更好的写代码

(1)作用域中的一个隐式属性[[scope]]

1、函数创建时,生成的一个JS内部的隐式属性,这个属性是js引擎来读取的

2、它是存储函数作用域链的容器

​ 作用域链存储其实就是我们所说的AO(函数的执行期上下文)/ GO(全局的执行期上下文)

​ 当函数执行完成以后,AO是要被销毁的,也就是说每次执行函数的时候会生成一个新的AO,

​ 也就是说AO是一个即时的存储容器

在这里插入图片描述

一定要记住,每一个函数的作用域链都是包含GO的,每一个函数在定义的时候就包含了全局执行上下文GO,

在执行函数的前一刻形成的AO。

记住,所有的自身的AO都是排在自身的作用域的最顶端的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tospBgAz-1638695796407)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001144031003.png)]
当外层函数被执行的时候,内层函数被定义,这是一个规律。

a函数被执行的时候,b函数被定义。

b函数被执行之前的作用域链和a函数被执行的时候的作用域链是一样的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9WX4a1Cb-1638695796407)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001144926671.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Pd6nlLf-1638695796407)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001145147393.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pDzEMe0V-1638695796408)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001145329285.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QM1nYrTA-1638695796408)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001145347388.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6V0NMs23-1638695796408)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001145454229.png)]

一定要记住,在函数被定义的时候生成作用域和作用域链,作用域链中已经存在GO了,在函数被执行的那一刻生成自己的AO

(二)、闭包

function test1(){
 function test2(){
    var b = 2;
    console.log(a);
 }
 var a = 1;
 return test2();
}
var c = 3;
var test3 = test1();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AswtXLT9-1638695796408)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001152746195.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xxyisvNA-1638695796408)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001152936713.png)]

test1在执行的时候,test2被定义,他们两个的作用域链是完全相同的[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r55fSWey-1638695796409)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001153319638.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kP7gBbsk-1638695796409)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001153707625.png)]

test3里面保存的是test2,test3执行的时候相当于执行了test2,test2一执行,生成自己的AO

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S09WuGIa-1638695796409)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001154344494.png)]

test1返回的是整个test2这个函数,test3执行其实就是执行test2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cj4s5W1J-1638695796409)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001154932442.png)]

闭包:当内部函数被返回到外部并保存时,一定会产生闭包

闭包会产生原来的作用域链不释放

,过度的闭包可能会导致内存泄露或加载过慢。

闭包例子:
闭包可以用来做数据缓存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-or8tZKTG-1638695796410)(/Users/liruize/Library/Application Support/typora-user-images/image-20211001160136159.png)]

可以用数组返回多个函数。

supply供应 sale出售

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K5D3O1mV-1638695796410)(/Users/liruize/Library/Application Support/typora-user-images/image-20211205171317171.png)]

function sunSched(){
			var sunSched = '';

			var operation = {
				setSched: function(thing){
					sunSched = thing;
				},
				showSched: function(){
					console.log("My schedule on sunday is " + sunSched);
				}
			}

			return operation;
}

var sunSched = sunSched();

sunSched.setSched('studying');
sunSched.showSched();
打印结果:
My schedule on sunday is studying

标签:闭包,test2,函数,作用域,基础,AO,sunSched,var
来源: https://blog.csdn.net/qq_43714814/article/details/121732160