javascript函数预解析基础上
console.log(num)
var num = 2
/*
控制台结果:undefined
----------------------------------------分隔线
预解析过程:javascript会把使用var声明的变量提升到代码的最前面,
var num 只定义未赋值所以结果为undefined
console.log(num)
num = 2
*/
fn();
function fn() {
console.log(123);
}
/*
控制台结果:123
---------------------------------------------分隔线
预解析过程:javascript会把申明式的函数提升到代码的开头,所以只要在script标签定义了函数,在当前script标签任意位置都可以调用,包括后面的所有script标签我们都可以调用
function fn() {
console.log(123);
}
fn();
*/
console.log(fn)
fn()
var fn = function () {
console.log(123);
}
/*控制台结果如下
undefined
Uncaught TypeError: fn is not a function
-----------------------------------------分隔线
预解析过程:我们观察上面的一段代码块,javascript首先会把使用var声明的变量和申明式函数提升到开头,赋值式的函数不会被提升,仅仅只提升前面的变量,预解析过程如下:
var fn;
console.log(fn) 只定义未赋值所以是undefined
fn() fn不是一个函数所以报错
fn = function () {
console.log(123)
}
*/
fun()
var fn = function () {
console.log('我是 fn 函数')
}
function fun() {
console.log('我是 fun 函数')
}
fn()
fn = 100
fn()
/*控制台结果:
我是 fun 函数
我是 fn 函数
Uncaught TypeError: fn is not a function
------------------------------------------分隔线
预解析过程:观察上面的代码,首先我们要把申明式的函数和使用var申明的变量提升到
function fun() {
console.log('我是 fun 函数')
}
var fn
fun()
fn = function () {
console.log('我是 fn 函数')
}
fn()
fn = 100
fn()
*/
在这里插入代码片
fn()
function fn() {
console.log('我是一个 fn 函数')
}
fn()
var fn = 100
fn()
/*
控制台结果如下:
2我是一个 fn 函数
TypeError: fn is not a function
--------------------------------------------------分隔线
预解析过程:
观察以上代码,首先javascript会把申明式函数和var申明的变量提升到script标签的最开头,那么当函数名和变量名重名,该如何提升,如果重名我们以一等公民函数为准
function fn() {
console.log('我是一个 fn 函数')
}
var fn; 变量名和函数名重名啦
fn()
fn()
fn = 100
fn()这里把100赋值给fn,数字100当作函数调用,所以会报错
*/
在这里插入代码片
var a = b
a = 0
b = 0
console.log(a)
console.log(b)
/*
控制台结果:
Uncaught ReferenceError: b is not defined
-----------------------------------------------分隔线
预解析过程:
var a;
a = b 当解析到b这里的时候,因为b在前面没有定义,所以程序会报错并终止,后面的程序也不会继续执行
*/
在这里插入代码片
var fun = 200
fun()
var fun = function () {
console.log('我是一个 fun 函数')
}
fun()
/*
控制台结果如下:
Uncaught TypeError: fun is not a function
预解析过程:
var fun;
var fun;
var fun = 200;
fun() 200数字,不是函数,报错:fun is not a function,底下的都不执行了
*/
在这里插入代码片
function fn(a) {
console.log('我是 fn 函数')
a()
function a() {
console.log('我是函数 a')
}
}
fn(10)
/*
控制台结果:
我是 fn 函数
hlh2.html:30 我是函数 a
---------------------------------------------------分隔线
预解析过程:当有内部函数时,函数里面的代码也要进行预解析,步骤如下
function fn(a) {
当有形式参数的时候,就相当于在函数里面定义了一个变量a,然后给a赋值 10,之后在执行函数内部的预解析,简单一句话就是函数内部的预解析是在给形参赋值之后
var a;
a = 10
function a(){
console.log('我是函数 a')
}
console.log('我是 fn 函数')
a()
}
fn(10)
*/
function fn() {
console.log(num)
return
var num = 8
}
fn()
/*
控制台结果:
undefined
----------------------------------------------------分隔线
预解析过程:
function fn() {
var num return后面的代码虽然不执行但是会预解析
console.log(num)
return
num = 8
}
fn()
*/
console.log(num)
if (false) {
var num = 100
}
/*
控制台结果: undefined
--------------------------------------------------分隔线
预解析过程:
var num ;
console.log(num) 即使后面代码不执行,变量也会预解析
if (false) {
num = 100
}
*/
```
小菜的总结:
A:预解析首先会找到var定义的变量,以及申明式函数提升到代码开头,对于赋值式函数提升的是变量名;
B:函数只要申明了,在当前script标签的任何位置,和后面的script标签都可以调用,变量也可以先输出,结果是undefined;
C:函数嵌套的时候,里面的函数也要预解析,如果有形式参数,则在给形参赋值之后;
D:在不执行的代码块里面,比如return后面,就算执行不到也会预解析,简单一句话,预解析无孔不入;
E:函数名和变量预解析重名的时候,已一等公民函数为准;