直接上代码
function b(){
function a(){ //函数声明置顶
console.log(a);
}
a = 10;
return;
}
var a;
a = 1;
b();
console.log(a);
在解析代码前先要弄明白什么是作用域,作用域在调用变量或者一个对象属性等的时候,查找的顺序是由里向外的,js执行代码是自上往下的。这个很重要
分析代码:
- 先声明变量a,系统给变量a分配一个内存,注意,这里变量a暂时还不知道它的变量类型,因为还没有赋值;
- a=1,给变量赋值为1,变量类型为number;
- 开始执行函数b,函数b内有一个函数名为a的函数声明,且函数a下面有一个变量名为a的变量,且赋值为10,这里便开始了难点分析。首先看函数a,由于在执行函数b的时候,并没有调用函数a,因此函数a并没有起作用;但是执行到a=10的时候,js是这样做的:1.首先查找变量a的地址,从系统内存中开始按照作用域链查找;2.由于作用域链的查找顺序是由里向外的,故要先从函数b里面开始查找;3.在查找的过程中,发现函数b中已经声明了一个函数名为a的函数(重名问题!),所以查找到函数名为a的函数后,这里便不再往外查找;4.所以这里的a=10其实是将10赋值给了函数名为a的这个函数对象!
代码1
var a;
function a(){
console.log(10);
}
console.log(a);
代码2
function a(){
console.log(10);
}
var a;
console.log(a);
运行后结果都是 //function a(){console.log(10)}。
函数声明置顶比变量声明置顶更优先,在预解析阶段变量只声明了,但未赋值,而函数不一样,它在预解析阶段就已经声明和赋值了,它的值就是函数这个对象,而在打印的时候,打印是需要出具体的值的,而变量还未赋值,函数却已赋值了,所以两次运行结果均是function a(){console.log(10)}。如果去掉函数a,运行的结果是undefined,是因为a被初始化并赋值为undefined了。
变量名与函数名重名的总结:
1.要知道js解析变量声明的顺序
2.函数声明和变量声明会置顶且函数声明更优先!
3.作用域链的查找顺序是由里向外,js执行代码顺序是自上往下
源地址:https://blog.csdn.net/charles_tian/article/details/79775909,这作者分析得已经很到位了。