Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
444 views
in Technique[技术] by (71.8m points)

js函数声明与window属性问题,解释一下结果

控制台运行结果:
微信图片_20200622100018.jpg

运行代码如下:

var a=0;
if(true){
    console.log(window.a,a);
    a=1;
    console.log(window.a,a);
    function a (){};
    console.log(window.a,a);
    a=21;
    console.log(window.a,a);
}
console.log(window.a,a);

麻烦大神解释一下,第三次打印结果为什么是1,1呢?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

首先要记住:函数声明置顶比变量声明置顶更优先

因为在预解析阶段变量只声明了,但未赋值,而函数不一样,它在预解析阶段就已经声明和赋值了,它的值就是函数这个对象

然后来看代码:
1、var a = 0:声明了一个变量a,并赋值为0
2、看if里面代码;我们先就看a=1function a(){}

// 因为存在变量提升,代码可以分析为这样,先不看console
function a(){}
a = 1

开始执行if代码块,if代码块内有一个函数名为a的函数声明,
且函数a下面有一个变量名为a的变量,且赋值为1,这里便开始了难点分析。

首先看函数a,由于在执行if代码块的时候,并没有调用函数a,因此函数a并没有起作用;
但是执行到a=1的时候,js是这样做的:

1.首先查找变量a的地址,从系统内存中开始按照作用域链查找;
2.由于作用域链的查找顺序是由里向外的,故要先从if代码块里面开始查找;
3.在查找的过程中,发现if代码块中已经声明了一个函数名为a的函数(重名问题!),
所以查找到函数名为a的函数后,这里便不再往外查找;

所以这里的a=1其实是将1赋值给了函数名为a的这个函数对象!

3、第一个consolewindow.a找的是全局的变量a,在全局下已经声明有了a,所以值为0,后面的a会现在if代码块里查找,变量提升了,所以打印的是function a(){}
4、执行到a=1;因为没有var关键字,所以a相当于一个全局变量,此时a就会覆盖原来a的值,变为1;而if代码块里也直接找寻到名为a的函数,所以将a赋值为1,因此第二个console值为 0, 1
5、第三个console,此时已经赋过一次值,在打印,就是1, 1
6、第四个consolea=21,在if代码块里查找,找到了函数名a,将值赋给了这个函数对象;所以这次打印的是1,21
7、第五个console,就是打印全局的a,所以是1, 1

以上就是我的理解,如果有错,欢迎指出,共同理解进步哈?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...