学习笔记 ——— 作用域 预编译

学函数的时候,偶然间发现了预编译,就突然很感兴趣,然后也看了许多博客,查了定义。也算是有了些了解,记录下来,当作笔记的开端。

预编译

提到预编译,就不得不说到javascript的运行。
javascript是解释性语言,顾名思义,就是编译一行,执行一行.。
那么在js中,在执行代码之前,还有两个步骤。
1, 语法分析,检查有没有低级的语法错误。
2, 预编译
3, 解释执行 执行代码

####预编译发生在什么时候
预编译发生在script代码块以及函数执行前发生。但是script代码块并没有多少,所以一般都是发生在函数执行前。

做了什么事

当页面产生的时候,script代码块开始执行,这个时候,就发生了预编译。
此时
1, 会创建一个GO全局对象(Global Object) // 也称为执行期上下文
2, 查找变量声明,作为GO属性,值赋予undefined
3, 查找函数声明, 作为GO属性,值赋予函数体
注意 他是按照先找变量声明再找函数声明的顺序来的,所以,如果变量名和函数名一样, 那么会覆盖。
这是发生在script代码块的预编译,发生在函数的预编译呢?

在函数执行之前

同样
1, 首先会创建一个AO全局对象 (Active Object)// 也称为执行期上下文
2, 查找形参和变量声明,值赋予undefined
3, 实参值赋予形参
4, 查找函数声明,值赋予函数体

函数预编译和代码块预编译基本一致,只不过,他们找的变量声明不一样。
凡是属于全局变量的变量声明,都属于GO,凡是属于局部变量的变量声明,都属于这个局部变量所在的函数的AO。任何变量,如果变量未声明就赋值,那么这个变量就属于全局变量,归AO所有。

不过说了这么多,预编译到底可以用来干什么呢?

有什么用

我们来看看这个

var a = true;
		foo();

		function foo() {
			if(a) {
				var a = 10;
			}
			console.log(a);
		}

打印的a是什么呢?
在打印之前,我i们不妨用预编译来试着编译一下。
根据预编译定义,我们先找到变量声明a,此时a是undefined,并没有被赋值,然后找到函数foo(),此时foo()是function(){}。
在函数执行前 给函数foo()创建一个AO对象,里面只有一个变量a的声明。为他赋值undefined。注意,预编译定义中,并没有说明任何有关于判断条件,所以,我们 不去管判断到底可不可以被执行,只需要把里面有的声明提生就行了。
然后,函数开始执行,因为变量提升的缘故,函数是先被执行的,此时,a并没有被赋值true,a直接被打印undefined.

预编译的大概就是这样,懂了预编译之后,我们再去看作用域其实就非常比较容易了。

如果声明变量的同时初始化或赋值那么变量优先级高于函数

作用域

一般说起作用域,第一反应肯定是全局作用域和局部作用域。
这么说,对是对,但是总感觉,对不起这么高大上的名字。

在javascript中,每个函数都是一个对象,对象中有的属性我们可以去访问他,但是有些是不可以的。
[[scope]]就是一个不能被访问的,仅仅供javascript引擎获取的。他就是我们所说的作用域,其中储存了执行期上下文的集合。这个集合呈链式链接,我们把这种链式链接叫做作用域链。

作用域链
var a = 1;
		function f(){
			var a = 2;
			function f2(){
				var a = 3;
				function f3(){
					console.log(a);
				}
				f3();
			}
			f2();
		}
		f();

这就是一个简单的作用域链
1, 先创建一个GO对象 他拥有变量a 函数f()
2, 在执行函数f() 创建函数f()的AO对象 声明变量a 函数f2()
3, 在执行函数f2() 创建他的AO对象, 声明变量a 函数f3()
4, 此时 要执行函数f3() 但是f3()内部并没有a 他就上他的父级上下文去找,如果富集没有就继续向上找,直到找到为止。

父亲上下文:这个函数在哪个上下文中被声明,那个上下文就是此函数的父亲上下文,这个函数的声明会被保存到父亲上下文的变量对象中。

执行期上下文

函数在执行时,会创建一个名为执行期上下文的内部对象,定义了函数执行时的环境.函数每次执行对应的执行上下文时,都是独一无二的,所以多次调用同一个函数,会创建不同的执行期上戏闻,当函数执行完毕,他所产生的执行期上下文会被销毁。

个人浅见,了解预解析和作用域,对以后学习闭包,平时做题的时候,更得心应手,可以清楚的知道为什么。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值