大家好,我是尤雨海。。。。。
一、先看一道题。
function fn(a, c) {
console.log(a);
var a = 123;
console.log(a);
console.log(c);
function a() {}
if (false) {
var d = 678;
}
console.log(d);
console.log(b);
var b = function () {};
console.log(b);
function c() {}
console.log(c);
}
fn(1, 2);
大神先别说话哦,小伙伴们告诉我从上到下的a,b,c,d会输出什么。
二、解析
废话不多说,上思路。
首先了解一下预编译。
想要搞明白这道题,首先就需要了解一下作用域的创建阶段,也就是预编译阶段,做了哪些事情,在函数作用域的创建阶段,与之相对应的也创建出来了一个js的变量对象,也称之为AO对象。这个对象是供js引擎自己去访问的。
函数作用域的创建阶段做了哪些事情呢??
第一个就是创建了AO对象。
AO{
}
第二个就是找形参和变量的声明,作为ao对象的属性名,值是undefined。
AO{
a:undefined
c:undefined
b:undefined
d:undefined
}
第三个就是形参和实参的相统一。
AO{
a:1
c:2
b:undefined
d:undefined
}
第四个就是找函数声明,并且如果函数声明的名称和变量声明的名称一致的话,函数声明会覆盖变量声明。
AO{
a: function a() {}
c: function c() {}
b:undefined //b是表达式声明,预编译后的值依然是undefined
d:undefined
}
接下来看一下执行结果。
根据上面的解析,执行结果应该是:
function fn(a, c) {
console.log(a); //function a() {}
var a = 123;
console.log(a); //123
console.log(c); //function c() {}
function a() {}
if (false) {
var d = 678;
} //条件不成立,无法赋值
console.log(d); //undefined
console.log(b); //undefined
var b = function () {};
console.log(b); //function () {}
function c() {}
console.log(c); //function c() {}
}
fn(1, 2);
看下浏览器的打印结果: