函数的预解析
预解析是什么?
在浏览器解析js中的代码之前, 会有一个 预解析阶段。在预解析阶段, 会将var 声明的变量、声明式定义的函数, 提升到
当前作用域的最顶端(提升到代码的最前面)
注意: 函数调用,执行函数内部代码之前,也会在函数内部进行预解析,函数内部的变量和函数,只会提升到函数内的最前面
- 只有var 声明变量和声明式定义的函数才会预解析
fun()
var fn = function () {
console.log('我是fn函数');
}
function fun() {
console.log('我是fun函数');
}
fn()
fn = 100
fn()
/*
// 预解析分析: 变量提升,函数提升
// var fn;
// function fun(){
// console.log('我是fun函数');
// }
// fun() // 正常函数调用
// fn = function () {
// console.log('我是fn函数');
// }
// fn() // 正常函数调用
// fn = 100
// fn() // 报错 此时fn的值是100
// */
var a = b;
a = 0
b = 0
console.log(a);
console.log(b);
// /*
// 预解析分析: 变量提升
// var a;
// a = b; // 此处执行的时候,变量b有声明,报错 b is not defined
// a = 0;
// b = 0;
// console.log(a);
// console.log(b);
// */
console.log( num ); // undefined
var num = 100;
console.log( num ); // 100
// /*
// 预解析分析:
// 代码执行之前,只要发现代码中有var 申明变量,会将var 声明变量提升到最前面
// var num;
// console.log( num ) // undefined,声明变量没有赋值,变量就是undefined
// num = 100
// console.log( num ) // 100
// */
fn();
function fn() {
console.log('fn')
}
fn();
// /*
// 预解析分析:
// 在代码执行之前,会将声明式定义的函数提升到最前面
// function fn() {
// console.log( 'fn' )
// }
// fn();
// fn();
// */
- 赋值式定义的函数不会函数提升预解析,只有可能会变量提升预解析
fn();
var fn = function () {
console.log('fn')
}
fn();
/*
预解析分析:
代码执行之前,发现有var 声明变量,会将变量声明提升到最前面
var fn;
fn(); // 此时变量fn中的值undefined,所以此处函数调用报错
fn = function () {
console.log('fn')
}
fn();
*/
fun();
var fun = 200
fun()
var fun = function(){
console.log('我是fn函数');
}
fun()
// /*
// 预解析分析:
// var fun;
// var fun;
// fun();// 报错fun is not a function 不再往下运行
// fun = 200
// fun()
// fun = function(){
// console.log('我是fn函数');
// }
// fun()
// */
- 函数调动的时候,函数内也会预解析,但是会先进行形参赋值,然后预解析
function fn() {
console.log(num)
var num = 100;
console.log(num)
}
fn();
/*
预解析分析:
fn函数调用,fn函数内部代码预解析
function fn(){
// 预解析
var num;
console.log(num) // undefined
num = 100;
console.log(num)// 100
}
*/
function fn(a){
console.log('我是fn函数');
a()
function a(){
console.log('我是a函数');
}
}
fn(10); //输出:我是fn函数 我是a函数
// 预解析分析: 函数调动时,函数内部的代码也会有预解析
// 但是如果函数调用的时候有形参赋值,则会先进行形参赋值,后预解析
// fn(10)函数调用,函数内:
// a = 10; // 形参a 是函数内的变量
// function a(){
// console.log('我是a函数');
// }
//形参变量a里面的值,原来是10,然后定义函数和a同名,所以将变量a中的值覆盖为一个函数了
// console.log('我是fn函数');
// a(); 此时a里面是一个函数,所以正常调用
- 函数内的return 不会影响函数内的预解析
function fn(){
console.log(num);
return; //return关键字只会终断代码的执行,会不影响预解析
var num = 100
}
fn();
// 预解析分析:
// 在函数内部,预解析; 函数内的return关键字只会终断代码的执行,会不影响预解析
// var num;
// console.log(num); // undefined
// return;
// num = 100
- 分支结构中的条件和大括号也不会影响预解析(变量提升)
console.log(num);
if(false){
var num = 100;
}
// /*
// 预解析分析:
// 在js条件分支中的预解析(变量提升),不会受到条件判断的影响,不受此处大括号的影响
// var num
// console.log(num); // undefined
// if(false){
// num = 100;
// }