●预解析 其实就是聊聊 js 代码的编译和执行
●js 是一个解释型语言,就是在代码执行之前,先对代码进行通读和解释,而后在执行代码
●也就是说,咱们的 js 代码在运行的时候,会经验两个环节 解释代码 和 执行代码
●JavaScript 引擎在对 JavaScript 代码进行解释执行之前,会对 JavaScript 代码进行预解析,在预解析阶段,会将以关键字 var 和 function 结尾的语句块提前进行解决
●处理过程:当变量和函数的申明处在作用域比拟靠后的地位的时候,变量和函数的申明会被晋升到作用域的结尾。
解释代码和执行代码
●因为是在所有代码执行之前进行解释,所以叫做 预解析(预解释)
●须要解释的内容有两个
○var 关键字
■在内存中先申明有一个变量名
■会把 var 关键字申明的变量进行提前阐明, 然而不进行赋值
○申明式函数
■在内存中先申明有一个变量名是函数名,并且这个名字代表的内容是一个函数
■也就是会把函数名进行提前申明, 并且赋值为一个函数
解析 var 关键字
// 1. 解析 var 关键字
console.log(num)
var num = 100
console.log(num)
代码剖析:
预解析
var num
通知浏览器, 我定义了一个叫做 num 的变量, 然而没有赋值
代码执行
第 1 行代码, 在控制台打印 num 变量的值
因为预解析的时候, 曾经申明过 num 变量, 只是没有赋值
num 变量是存在的
打印进去的是 undefined
第 2 行代码, num = 100
给曾经定义好的 num 变量赋值为 100 这个数据
第 3 行代码, 在控制台打印 num 变量的值
因为第 2 行代码的执行, num 曾经被赋值为 100 了
此时打印进去的内容是 100
解析赋值式函数
●赋值式函数会依照 var 关键字的规定进行预解析
fn()
var fn = function() { console.log('fn 函数') }
fn()
○代码剖析:
预解析
var fn
通知浏览器我定义了一个叫做 fn 的变量, 然而没有赋值
代码执行
第 1 行代码, fn()
拿到 fn 变量存储的值当做一个函数来调用一下
因为 fn 只是申明了变量, 并没有赋值, 所以 fn 是一个 undefined
咱们做的事件是, 把 undefined 当做一个函数来调用
报错: fn is not a function
解析申明式函数
// 解析申明式函数
fn()
function fn() { console.log('fn 函数') }
fn()
代码剖析:
预解析
function fn() { console.log(‘fn 函数 ’) }
通知浏览器, 我定义了一个 fn 变量, 并且 fn 变量保留的内容是一个函数
代码执行
第 1 行代码, fn()
拿到 fn 变量存储的值, 当做一个函数来调用
因为预解析阶段 fn 存储的就是一个函数
调用没有问题
第 3 行代码, fn()
拿到 fn 变量存储的值, 当做一个函数来调用
因为预解析阶段 fn 存储的就是一个函数
调用没有问题
预解析优先级
fn()
console.log(num)
function fn() {console.log('我是 fn 函数')
}
var num = 100
通过预解析之后能够变形为
function fn() {console.log('我是 fn 函数')
}
var num
fn()
console.log(num)
num = 100
预解析中重名问题
1. 当你应用 var 定义变量 和 申明式函数 重名的时候, 以 函数为主
2. 只限于在预解析阶段, 以函数为准
案例 1
num()
var num = 100
num()
function num() { console.log('我是 num 函数') }
num()
○代码剖析:
预解析
var num
通知浏览器我定义了一个叫做 num 的变量, 然而并没有赋值
function num() { console.log(‘ 我是 num 函数 ’) }
通知浏览器我定义了一个叫做 num 的变量, 并且赋值为一个函数
预解析完结阶段, num 变量存在, 并且是一个函数
执行代码
第 1 行代码, num()
拿到 num 的值当做一个函数来调用
因为预解析阶段, num 就是一个函数
所以失常调用
第 2 行代码, num = 100
给 num 变量赋值为 100
因为 num 自身保留的是一个函数, 当初赋值为 100
就把 函数 笼罩了, 一个变量只能保留一个值
从此以后, num 就是 100 了
第 3 行代码, num()
拿到 num 的值当做一个函数来调用
因为第 2 行的代码执行, 曾经把 num 赋值为 100
此时就是把 数字 100 当做一个函数来调用
报错: num is not a function
案例 2
num()
function num() { console.log('我是 num 函数') }
num()
var num = 100
num()
○代码剖析:
预解析
function num() { console.log(‘ 我是 num 函数 ’) }
通知浏览器, 我定义了一个叫做 num 的变量, 并且赋值为一个函数
var num
通知浏览器, 我定义了一个叫做 num 的变量, 然而没有赋值
预解析完结的时候, num 变量存在, 并且是一个函数
代码执行
第 1 行代码, num()
把 num 存储的值拿来当做一个函数调用
因为预解析阶段, 确定了 num 就是一个函数
调用没有问题
第 3 行代码, num()
把 num 存储的值拿来当做一个函数调用
因为预解析阶段, 确定了 num 就是一个函数
调用没有问题
第 4 行代码, num = 100
把 num 赋值为 100
自身保留的函数就被笼罩了
从此以后, num 就是 100 了
第 5 行代码, num()
把 num 存储的值拿来当做一个函数调用
因为第 4 行代码的执行, 导致 num 是一个 数字 100
把 数字 100 当做函数调用
报错: num is not a function
预解析中非凡状况
●在代码中, 不论 if 条件是否为 true, if 语句代码外面的内容依旧会进行预解析
// 预解析的非凡状况
// 1. if 语句
console.log(num) // undefined
if (true) {
// 第一件事: var num
// 第二件事: num = 100
var num = 100
}
console.log(num)
函数体内, return 前面的代码尽管不执行, 然而会进行预解析
// 预解析的非凡状况
// 2.return 前面
function fn() {console.log('我是 fn 内的代码')
console.log(num) // undefined
return
// 第一件事: var num
// 第二件事: num = 100
var num = 100
console.log(num)
}
fn()