关于Js中预解析的一些案例分析
通过个人的理解,预解析就是JS在代码执行过程中,会将代码中的一些变量个函数预解析加载到内存中
案例一:
下面看一下一些小小的案例
console.log(a);
var a = 10;
输出结果:
undefined
代码分析:在js代码的执行过程中,输出变量a在前,但是变量a的定义在后,所以JS在预解析的时候会将变量的声明放到前面去,然后输出变量的时候就是未定义了类似于下面的代码:
var a;
console.log(a);
a = 10;
案例二:
console.log(a);
var a = 10;
function a(){
console.log("Hello");
}
输出结果:
function a(){
console.log("Hello");
}
代码分析:同样,在js的执行过程中,会将变量a和函数a的声明进行提前,所以在输出的时候,会输出函数a,开始的时候以为是在预解析的时候先声明的变量a后声明的函数a,所以会输出函数a,我将变量a和函数a变换了位置之后,发现还是输出的函数a,所以我觉得这里可能是有一个优先级的问题,函数的优先级会高于变量
案例三
var a= 10;
function f1(){
console.log(a);
var a = 20;
}
f1();
输出结果:
undefined
代码分析:这里为什么输出的是undefined不是10呢,首先JS有一个定义域链的问题,就是在函数中,如果存在变量a,那么函数就会使用变量a,如果没有变量a,这时候就会使用全局变量a,而在函数内,由于局部变量a被预解析,函数体内在输出a的时候,就成了undefined,如果删掉了var a = 20 的声明,这时候就会输出10了,类似于如下代码:
var a= 10;
function f1(){
var a;
console.log(a);
a = 20;
}
f1();
案例四:
f1();
console.log(b);
console.log(c);
console.log(a); //这里我将a最后打印是为了出现像
function f1() {
var a = b = c = 10;
console.log(a);
console.log(b);
console.log(c);
}
输出结果:
>10
>10
>10
>10
>10
>报错(报错信息就不贴了)
代码分析:在函数f1()中打印a、b、c三个数的值都是10这没意见,为什么在外面打印b、c的值也是10,打印a的时候直接报错了呢。其实var a = b = c = 10这一长串代码可以分拆为 var a = 10; b = 10; c = 10;注意在函数中,变量a前面使用了var声明,而变量b和c都没有使用var声明,这就说明b个c是属于隐式全局变量,而a属于局部变量,所以在外部访问b和c的时候都能访问到,而打印a的时候,由于a未声明,所以直接报错,类似于一下代码:
f1();
console.log(b);
console.log(c);
console.log(a);
function f1() {
var a = 10; //局部变量
b = 10; //隐式全局变量
c = 10; //隐式全局变量
console.log(a);
console.log(b);
console.log(c);
}
案例五:
f1();
var f1 = function () {
console.log(a);
var a = 10;
}
输出结果:
>>Uncaught TypeError: f1 is not a function 报错
代码分析: 这里使用了一个变量f1来存储一个函数,而在调用f1的时候,同样由于预解析的存在,会直接将变量f1进行预解析var f1;而预解析之后造成的结果就是f1根本就不再是一个函数而成了一个undefined的变量,这时候在对这个undefined的变量进行函数调用,这时候就会出现f1 is not a function的错误;代码类似于:
var f1;
f1();
var f1 = function () {
console.log(a);
var a = 10;
}