javascipt是一种描述型的脚本语言,是一种解析语言,由浏览器动态解析,不同种类浏览器不同版本的浏览器对js的解析有着微小的差别,不同浏览器js解析引擎效率也有高低。
js的执行过程分为两大部分:
第一部分,解析过程,也称预编译期。主要工作就是对js代码中声明的所有变量进行预处理。需要注意的是,在此进行处理的仅是声明函数,而对于变量的处理仅是声明,并开辟出一块内存空间,不进行赋值操作。
第二部分,执行过程,在执行过程中,浏览器的js引擎对每块代码进行顺序执行,如果有外部引用的js,且js有相互关联,此时就要注意,不同的js的引入顺序,如果声明代码块在调用代码块后调用则将不会达到预期效果。
总的来说,js的执行分为两部分,解析过程和执行过程。解析时按照代码代码块,一段一段进行解析,执行时按照代码块顺序逐行执行,解析一个代码块执行一个代码块。
因为是解释性语言,所以js如果在解析过程中有错误,则不会提示,也可以理解为js不会出现编译错误,但如果出现了运行时错误。
var ad;//预处理阶段处理
ad = 1;//运行时赋值
function text(){
console.log(1);
if(ad){//boolea
}
}
为什么变量是在运行时赋值的而不是在预处理阶段进行赋值?
因为javascript的变量的数据类型不是固定的,要根据当前运行的情况的判定。
全局预处理阶段预处理:创建一个词法环境(LexicalEnvironment,在后面简写成LE),扫描JS中的用声明的方式声明函数,用var定义的变量并将他们加到预处理阶段中的词法环境中去。
预处理阶段先读取代码块,不是一行一行的解析执行定义的方法和var定义的变量,会放到一个(不同的环境,会有对应语法的环境)词法环境中
var a = 1;
var b;
c = 3;
function d(){
console.log('hello');
}
var e = function(){
console.log('world');
}
词法环境:
LE{//此时的LE相当于window
a:undefined
b:undefined
没有c
d:对一个函数的引用
e:undefined
}
预处理的函数必须是JS用声明的方式声明函数(不是函数表达式)
示例:
d();
e();
function d(){//用声明的方式声明函数
console.log('hello');
}
var e = function(){//函数表达式
console.log('world');
}
词法环境:
LE{//此时的LE相当于window
d:对函数的一个引用
e:undefined
}
结果:hello;报错e is not a function
命名冲突变量和函数同名冲突–函数优先,函数是一等公民,在既有函数声明又有变量声明的时候,函数声明的权重总是高一些,所以最终结果往往是指向函数声明的引用。
function f(){console.log(2);}
var f = 1;
console.log(f);
console.log(f)结果是2
function fa(){
var f = 3;
console.log(2);
}
var f = 1;
console.log(f);
console.log(f)结果是1
执行阶段console.log(a);
console.log(b);
console.log(c);
console.log(d);
var a = 1;
b = 2;
console.log(b);
function c(){
console.log('c');
}
var d = function(){
console.log('d')
}
console.log(d)
LE{
a:undifined
没有b
c:对函数的一个引用
d:undefine
}
结果:
undefined
报错
function c(){console.log('c');}
undefined
注释上面代码第二行
1.在第6行代码执行完,LE中的a值变为1;
LE{
a:1
没有b
c:对函数的一个引用
d:undefine
}
2.第7行代码执行完,LE中就有了b的值(且b的值为2,此时b的值直接变为全局变量)
LE{
a:1
b:2
c:对函数的一个引用
d:undefine
}
3.第10行代码执行完
LE{
a:1
b:2
c:指向函数
d:undefine
}
3.第14行代码执行完
LE{
a:1
b:2
c:指向函数
d:指向函数
}
函数冲突原则
1.处理函数声明有冲突时,会覆盖。
2.处理变量声明有冲突,会忽略。以传入参数的值为准。
预处理阶段传入参数值一 一对应
function f(a,b){
alert(a);
alert(b);
var b = 100;
function a(){}
f(1,2);
}
LE{
b:2
a:指向函数的引用
arguments:2
//arguments调用函数时实际调用的参数个数
}
js程序bug:函数内没有使用var声明的变量是全局变量。