预编译与作用域链
Posted zhangli123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了预编译与作用域链相关的知识,希望对你有一定的参考价值。
1.js代码是怎样执行的?
首先我们要知道js是一种解释型语言,代码是从上往下执行,足行依次往下执行,我们还要知道整个代码运行主要分两个阶段,这两个阶段分为预编译与执行。
2.预编译
从这个名字我们就可以看出来,我们的预编译都是在函数执行之前就开始进行的。
预编译就是,在函数执行前,所有的var变量提前声名(变量的值还是留在原地)和函数的整体提前,说白了就是在函数的最前面完成的
函数中的预编译一般分这几步:
(1)任何函数在执行前都会创建AO活动对象
(2)然后将我们要提前声名的变量,提前声名一般是var关键字的声名(此时的值是undefined,函数除外)
(3)然后再找相对应的值往里面带入
(4)最后再找函数的声名,并把这个函数赋值给这个变量
我们举个例子:
function fun(a , b , c){
console.log(a);//function a(){}
console.log(b);//undefined
function a(){};
var a=b=100;
console.log(a);//100
console.log(b);//100
var b = function(){};
console.log(b)//function(){}
}
fun(3);
我们可以根据上面的公式来找
此时的AO里面只有a和b,并且值都是undefined
然后执行第三步:此时a的值是3,b的值还是undefined
然后执行第4步:此时a的值是function a(){},b的值还是undefined
最后函数从上往下执行结果如上
3.Active Object 活动对象(抽象的)
执行环境:
js代码执行是有环境的(全局环境,函数内部环境)
该环境定义了其有权访问的其他数据
环境有一个与之关联的"活动对象AO"
环境中所以的变量和函数都是活动对象AO的属性
全局环境是最外围的执行环境,活动对象是window对象
执行环境中的代码执行完毕后就被销毁
4.我们的函数在解释执行时,首先要弄清楚当前的作用域,作用域分两种,一种是全局作用域,另一种是局部的作用域,其实这两个作用域的的区别也很简单
全局作用域:首先我们可以先找到全局变量,根据全局变量来判定是不是全局作用域,有的人可能又问怎样找全局变量,全局变量就是在函数当中,不用var关键字声明的变量,还有就是,直接在函数
外面声名的变量,其实就是在window下的(这只是个人理解,还是要根据实际情况)
局部作用域:局部作用域恰好和它相反在函数内部用var声名的变量(经供参考)
5.还有一个全局预编译
在执行前先创建GO函数作用域然后在创建AO活动对象其实步骤跟上面的活动对象差不多
此时全局预编译就形成了一个作用域链
6.什么是作用域链
作用域链就像我们生活当中的铁链子一样,一环扣一环
我们打个比方,就像我们有多个函数嵌套在一起,在这个函数还没有执行前,我们的全局预编译就开始执行了,此时的就创建了一个GO(此时的GO里面就是最外面的函数体)函数执行时现在最外面的AO活动对象就是第二个函数体,第二个函数的预编译就是第一AO和GO,函数执行时就是AO活动对象就是第二·个AO和第一AO和GO,就是这样的一层关系,就形成了作用域链。
7.作用域链的作用
7.1 变量必须"先声明,后使用"
函数可以"先使用,后声明",原因是函数有预加载的过程(函数声明先于其他执行代码进入内存).本质还是函数声明在前,使用在后.
7.2 内部环境变量可以访问外部环境的变量,反之不然.
环境: 每一个函数内部都是一个环境,最外边是全局环境.
类型: 函数环境、全局环境
7.3 变量的作用域是声明时觉得的,而不是运行时
8.优先级
执行环节可以访问变量的类型及优先顺序
内部变量>>>内部函数>>>形参>>>外部变量(函数,形参);
以上是关于预编译与作用域链的主要内容,如果未能解决你的问题,请参考以下文章