预编译目的
1. 定义作用域中的初始化词法环境,而词法环境中有定于作用域,从而规定了变量的作用域
2. 先是在为undefined,减少运行时报错
形参去实参的区别
1.形参变量只有在被调用时才分配内存单元,在调用结束时, 即刻释放所分配的内存单元。因此,形参只有在函数内部有效。 函数调用结束返回主调函数后则不能再使用该形参变量。
2.实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。 因此应预先用赋值,输入等办法使实参获得确定值。
function add(a,b) {
return a + b
};
add(1,2);
// a,b是形参,1.2是实参
JavaScript运行三部曲
脚本执行js引擎都做了什么呢?
- 语法分析
- 预编译
- 解释执行
1.语法分析:分析语法是不是错了
2在语句执行的时候会先进行预编译
3.在编译完了进行语句执行
下面就是编译的主要步骤
预编译的过程(分四步):
1.(对函数)创建AO对象;(对全局的时候也就是Window)创建GO对象
2.找形参和变量声明,将变量名和形参名作为(AO对象,或GO对象)的属性值 初始值为undefined
3.将实参值传递形参统一
4.在函数体里面找函数声明,值赋予函数体
A0,GO就是执行期的上下文定义了一个函数的执行环境(词汇环境),当一个函数在执行的前一刻,会创建一个执行期上下文(执行上下文创建的时间),并且每次在函数执行的时候这个执行期上下文都是不相同的,因为没一次都是全新的
在预编译和执行的过程会对赋值语句会对AO,GO中的变量进行覆盖,应该以执行结束后的结果为最终的变量标准。
当出现同命的时候函数为什么会覆盖变量应为函数是第4步变量是第二步就复制了,所以会函数的优先级高
下面是一个例子的全过程:
<script type="text/javascript">
global = 100;
function fn(){
console.log(global); //undefined
global = 200;
console.log(global); //200
var global = 300;
}
fn();
var global;
</script>
第一阶段全局预编译
1.首先全局对象创建GO执行上下文
GO{
2.对形参和变量声明,将其作为属性名,值为undefined
global:undefined
3.全局对象没有形参
4.在函数体里找函数声明,值赋予函数体
fn:function fn(){};
}
第二阶段执行代码
1. global = 100
2.fn();(先预编译fn(),在执行)
第三阶段 :由于fn函数要执行了先对其进行预编译
1. 对函数产生AO环境
AO{
2.对形参和变量声明,将其作为属性名,值为undefined
//当局部变量AO中存在的时候先找局部变量AO里的变量,这个时候虽然GO全局中存在global为100,但局部中已经有global为undefined
global:undefined --fn的AO执行到第二句-->200 --fn的AO执行到第四句-->300
3.没形参
4.没函数声明
}
第四步:执行fn()
A0执行{
第一句:console.log(global); //undefined在AO的执行上线中global:undefined;
第二句:global = 200;
第三句:console.log(global); //在AO中找global已经变成了200
第四句:global = 300; //
}
最终结果
GO{
global:100
fn:function fn(){ };
}
AO{
global:300
}
只有把这个看懂了(看懂一点也没关系)下面我们来写什么是作用域链 ,看完了什么是
作用域链
函数也是一个对象在这个对象中有些我们可以访问的属性比如prototype,name,不可以访问的有[[scope]]属性
[[scope]]属性:指的就是我们所说的作用域,其中储存了运行期上下文(执行期上线下文A0 G0)的集合
作用域链:[[scope]]中储存的执行期上下文对象的集合,这个集合呈链式链接,也叫作用域链
下面看一个例子
function a() {
function b() {
var b = 234;
}
var a = 123;
b();
}
var glob = 100;
a();
图一:在b定义的时候a马上快执行完的时候的图像
图二:在b自己执行的时候会变成
当b执行的时候:首先b会继承了aAO和GO,这里的aAO全等于a中的aAO
scope chain(栈的形式:先进后出)中的数值代表数值的key,key代表:
- 0 ---自己的AO(Activation Object)
- 1---a的AO
- 2---GO(Clobal Object)
由于由作用链的关心才可以说(0--自己OA中没有的变量)可以向上(1---a中的OA)找或者(2---GO)中找,也为以后闭包产生做铺垫
子 - 父 -祖宗--全局 这样一个(作用域链)的过程
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)