之前对JavaScript的底层运行机制不是很了解,错了很多面试图,痛定思痛,决定认真对待 JavaScript,好好了解一下它.
JavaScript代码运行前,有一个类似编译的过程,叫做词法分析,就是分析代码或函数的一些变量,声明,对于重复命名的变量的处理.
词法分析主要有三个步骤:
具体步骤如下:
函数在运行前,会生成一个活动对象我们叫做 Active Object 简称AO
函数接收形式参数,添加到AO的属性中,并且这个时候属性的值是 如:
这个时候函数接收到的是实参, 那么 在这个词法分析的阶段name就是27
如var name; var name = function () {} var name = 27
如果上一步分析参数中AO还没有name属性,则添加AO属性为undefine,即AO.name = undefine
如果AO上面已经有了name属性,则不作任何修改
如果有function name () {} 把函数赋值给AO.name 则覆盖上一步分析的值
看一段练手的代码
function func(name) {
console.log(name)
var name = 25;
console.log(name)
function name () {
}
console.log(name)
}
func(18)
词法分析:
第一步:分析函数参数
形参: AO.name = undefine
实参:AO.name = 18
第二步:分析局部变量
第三行代码有var name,但此时第一步已经有AO.name = 18 故不作任何改变
即AO.name = 18
第三步:分析函数声明
第五行代码有函数name, 则将function name(){} 付给AO.name 即AO.name = function name (){}
所以执行代码时:
第2行代码执行时,拿到name时词法分析后的AO.name 结果是 function name () {};
第3行代码 25 赋值给name 此时name = 25
第4行代码运行时name已经是25了,故结果是25
第5,6行代码时一个函数表达式,所以不会做任何操作;
第7行的结果依然是name=25
词法分析应该注意var name = function () {} 这样一个语句,参与了第二步和第三步 ;
执行代码时应注意函数表达式不做任何操作,且只声明变量没赋值时,nane仍然等于AO.name
下面给大家几个试炼题
// 例子2
function func (name) {
var name;
console.log(name)
var name = 25;
console.log(name)
function name () {}
console.log(name)
}
// 例子3
function func (name) {
var name;
console.log(name)
var name = 25;
console.log(name)
function name () {
console.log(name)
}
name()
console.log(name)
}
func(18)
// 例子4
function func (name) {
var name
console.log(name)
function name () {
console.log(name)
}
name()
console.log(name)
}
func(18)
// 例子5
function func (name) {
console.log(name)
var name = function name () {
console.log(name)
}
console.log(name)
}
func(18)