JavaScript预编译,作用域,闭包基础学习(二)

预编译

虽然JavaScript作为一款单线程,解释性的语言,但他也具备预编译的过程,在预编译期间,会提升相关的声明,和检查一些基础的语法错误。首先我们需要理解一些知识点,才能更好的理解预编译。
未加声明的变量使用,相当于定义在全局变量(即便在函数中使用)

	b = 100  //相当于定义全局变量 var b = 100

函数预编译

我们先从函数预编译讲起,预编译发生在函数即将开始之前,他会做如下几个步骤,来调解我们的重名定义。

  • 创建AO对象,即Activation Object(作用域上下文)
  • 找函数形参和变量声明,将其作为AO属性名,值为undefined。
  • 将实参值和形参相统一,并赋值于AO。
  • 在函数体找到函数声明,将其作为AO属性名,值为对应函数体。
    (对象中不可出现重名定义,所以根据规则和顺序覆盖,函数体的权重最高。)

全局预编译

类似于上述步骤,全局预编译发生在全局运行的前一刻,由于全局没有形参,所以省略函数预编译的第三步即可,其次全局生成的称之为GO,即Global Object,我们在这里可以将GO理解为window,所以全局变量我们也可以用window.变量名的方式来调用。

练习题

function test() {
    
    
	console.log(b);
	if(a){
    
    
		var b = 100;
	}
	console.log(b);
	c = 234;
	console.log(c);
}
var a;
test();
a = 10;
console.log(c)

根据我们以上步骤来理解这道练习题,得出的结果应为:

undefined
undefined
234
234

作用域

每个JavaScript的函数都是一个对象,对象中有些属性我们不能访问,仅供js引擎使用而提供,例如[[scope]],也就是我们所说的作用域,其中存储了运行期上下文的集合。
作用域链:[[scope]]中所存储的执行期上下文对象的集合
在这里插入图片描述
在这里插入图片描述
执行器上下文在函数开始前创建,函数运行结束时自动销毁。当函数需要寻值时,在作用域链子中自上而下寻找。即只能内层函数调用外层变量,外层函数不能调用内层变量。

闭包

当函数内部定义的函数被保存于函数外,导致函数资源泄露,我们可以称之为闭包。如下形式展示:

function a() {
    
    
	var num = 10;
	function b() {
    
    
		num++;
		console.log(num)
	}
	return b;
}
var dome = b;
dome();

我们在a函数外部用dome变量来接收b函数,使得可以直接抛开a去调b,从而修改了a函数中的变量值,根据我们作用域所理解的知识,当完成一个函数的使用,会自动销毁当前函数所生成的作用域上下文联系,但函数内部定义的子函数将继续保留,通过继承得到的父函数作用域上下文关系,所以即使不能通过函数a访问到num变量,我们依旧可以通过外部保留的函数b去访问num变量。
在一些编程设计里,如果我们巧妙地使用闭包,会带给我们很多好处,例如累加求和,或者制作缓存。
但是如果我们不经意间误用了闭包,可能会适得其反,且很难排查出错误。

function a() {
    
    
	arr[];
	for(var i = 0;i < 5;i++){
    
    
		arr[i] = function b() {
    
    
			console.log(i+" ");
		}
	}
	return arr[];
}
var demo = a();
for(j = 0;j < 5;j++){
    
    
	document.write(arr[j]);
}
function a() {
    
    
	arr[];
	for(var i = 0;i < 5;i++){
    
    
	(function (j) {
    
    
		arr[j] = function b() {
    
    
				console.log(j+" ");
			}
	}(i))
	return arr[];
}
var demo = a();
for(j = 0;j < 5;j++){
    
    
	document.write(arr[j]);
}

好好理解这2道题,虽然代码几乎相同,但是两个程序的结果却截然不同,第一个输出的结果为“5 5 5 5 5”,第二个输出的结果为“0 1 2 3 4”,很巧妙的利用作用域,闭包,立即执行函数的知识去分析这两道题,就能够求出正确答案。

猜你喜欢

转载自blog.csdn.net/baldicoot_/article/details/106189177
今日推荐