-
js代码运行是一条一条的解释,而在解释前要进行的工作 就是语法分析,对全部语句进行一步检查,判断是否符合基本语法规则。
-
-
一切未经声明的变量都是全局变量,属于全局作用域window所有
a = 1;
不会报错,在全局范围内相当于
var a = 1;
a属于全局window,在全局的作用域内,但是不提倡这样。
再来看一段
function my(){ var a = b = 3; }
变量的赋值从右到左,相当于西安将3赋值给了b,然后a的值等于b。但是此时只有a被声明,b并未声明,所以b属于全局变量,作用域在window,而a则是局部变量,属于函数my;
-
变量 声明提升;函数声明整体提升。看例子
var a = 1; console.log(a);
此时打印出结果为 1 ;
console.log(a); var a = 1;
将a定义到输出下面,但是并不会报错。此时a的定义可分为倆步。
var a; //声明 a; a = 1; //给a赋初值;
当a被声明时,同时被提升到了作用域的顶端,所以相当于
var a; console.log(a); a = 1;
因此,打印出的是undefined;再来看
function my(){ var b = 1; console.log(b); } my();
会打印出 1,没有问题
my(); function my(){ var b = 1; console.log(b); }
同样会打印出1.在js中,当函数被声明时他就被提到了作用域的顶端,而且是整个函数都被提升了,因此,my()函数执行无误;
在js代码执行前会创建一个GO对象,也就是全局作用域,而在每个函数执行前一刻会创建自己的AO对象,也称执行期上下文,看下面一段代码
function my(a){ console.log(a); var a = 123; console.log(a); function a(){} console.log(a); var b = function(){} console.log(b); function d(){}; } my(1);
在这个函数执行前,首先创建一个自己的AO对象(执行期上下文)
AO{ }
第二步
AO{ a:undefined; b:undefined; }
形参为a,变量声明为a和b,全部赋值undefined
第三步
AO{ a:1; b:undefined; }
a的实参为1.b无实参
第四步
AO{ a:function a (){}; b:undefined; d:function d (){} }
找到函数声明并赋予,至于function b仅仅是一个函数表达式,并不是函数声明,至此,AO对象创建完毕,开始执行函数。这里有几个注意点
-
声明的函数和变量在函数执行时忽略,因为都提升到了顶端
-
对于 var a = 123; var b = function(){};这样的声明,虽然变量声明被提升了,但是前面讲过,这些语句可分为俩段。
var a; a = 123; var b; b = function(){};
因此,var a 与var b被提升忽略不看,但是俩条赋值语句仍在原地,当解释执行到此时会理所当然地将值赋予给变量。
所以最后的打印结果应该是
function a(){} 123; 123; function b(){};
总的来说,变量声明提升和函数提升势必要覆盖其中一个,有一定的执行顺序,结果就是函数覆盖了变量。根据上面4点从后往前的访问顺序执行函数。
GO即全局作用域,既然AO是在函数执行前一刻创建的,那么GO则是在window加载前一刻创建的全局执行期上下文,创建规则与AO相同。而对于函数
-
-
-
当上述预编译执行完毕后,形成了GO和AO对象,js代码就可逐条执行,叫做解释执行,相关的作用域链在下一次介绍。