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是一个即时的存储容器

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

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

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

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

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

6-作用域与作用域链、闭包基础
当外层函数被执行的时候,内层函数被定义,这是一个规律。

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

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

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

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

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

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

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

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

(二)、闭包

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

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

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

test1在执行的时候,test2被定义,他们两个的作用域链是完全相同的6-作用域与作用域链、闭包基础

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

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

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

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

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

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

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

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

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

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

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

supply供应 sale出售

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

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

上一篇:js 检测页面刷新或关闭


下一篇:知识融合:一文看懂Falcon-Ao理论基础