1.js的运行和预编译过程
<1>.语法分析
查找基本语法有无错误;
<2>、预解析/预编译
执行之前进行预解析;
var,function关键字提前到当前作用域顶部,即变量提升或函数提升,变量默认值为undefined,函数默认值为函数体代码块,当函数与变量重名时,保留函数。
<3>、解释执行
2.例题
1)、变量可以在使用后声明,也就是变量可以先使用后声明
x = 5; // 变量 x 设置为 5
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x; // 在元素中显示 x
var x; // 声明 x
变量 提升之后
var x; // 声明 x
x = 5; // 变量 x 设置为 5
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x;
2)只有声明的变量会提升,而初始化的不会
例1.var x = 5; // 初始化 x
var y = 7; // 初始化 y
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y;// 显示 x 和 y
对比
例2、var x = 5; // 初始化 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y;// 显示 x 和 y
var y = 7; // 初始化 y
此例中y的输出值为undefined,这是因为变量声名(var y)提升了,但是y=7没有提升,所以y变量是一个没有定义的变量。
变量提升之后
var x = 5; // 初始化 x
var y; // 声明 y
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y; // 显示 x 和 yy = 7; // 设置 y 为 7
3)、其他一些例题
//预编译
/* console.log(a);
var a = 10; //变量提升
console.log(a); */
/* 提升之后的结果
var a;
console.log(a);
a = 10; */
4)、局部作用域中的变量提升
/* var b = 10;
function foo(){
console.log(b);
var b = 20;
}
foo(); */
/*// 提升之后的结果
var b = 10;
function foo(){
var b;
console.log(b);
b = 20;
}
foo();
*/
函数提升
例题
//函数提升(包括函数体一块提升)
/* bar();
function bar(){
alert(123);
} */
//通过function关键字申明的函数会连着函数体一块提升到当前作用域顶部
//但是通过变量名赋值为一个匿名函数的方式申明的函数,只会提升变量的申明,函数体不会提升
/* bar();
var bar = function(){
alert(456);
} */
/* 提升之后的,会报错
var bar;
bar();
bar = function(){
alert(456);
} */
注意:1.局部变量只作用于函数内部,所以不同的函数可以使用相同名称的变量
2、局部变量在函数开始时创建,在函数执行完成之后销毁。(局部变量出栈即销毁)
3、如果变量在函数内没有var即没有声明,该变量为全局变量。
例题
/* alert(a);
var a = 1;
alert(a);
function a(){alert(2);}
alert(a);
var a = 3;
alert(a);
function a(){alert(3);}
alert(a);*/
预编译之后
/* function a(){alert(3);}
alert(a); //function a(){alert(3);}
a = 1;
alert(a); //1
alert(a); //1
a = 3;
alert(a); //3
alert(a); //3 */