控制台运行结果:
运行代码如下:
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呢?
控制台运行结果:
运行代码如下:
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呢?
// 先进行变量提升
var a=0; // global 变量 a = 0
if(true){
// 变量提升
function a (){}; // block 变量 a 是函数
console.log(window.a,a); // 0, function(){}
a=1; // block 变量 a = 1;
console.log(window.a,a); // 0, 1
// 当局部变量有两个同名对象时,先执行的对象会将自身的具备特性赋给后面的变量,
// 此时函数声明是 global 变量,所以会把 1 赋值给 window.a
function a (){};
console.log(window.a,a); // 1, 1
a=21; // block 变量 a = 21
console.log(window.a,a); // 1, 21
}
console.log(window.a,a); // 1, 1
这题见过不下五次,每次也没特别好的解释,现在的答案也是我通过打断点,和查阅一些文章得出的结论,仅供参考,欢迎讨论。
附上参考链接:
https://my.oschina.net/zzjweb...
https://segmentfault.com/a/11...
看到过的类似的内容:
https://stackoverflow.com/que...
https://stackoverflow.com/que...
所以应该可以理解为:
var a0 = undefined;
// if 语句块内的函数声明的标识符 a 和外面的 var a 是同名的。为了后续表达方便,加个后缀
a0 = 0;
if (true) {
var a1 = function a() {};
console.log(window.a, a);
// 即 console.log(a0, a1),下同
// 所以打印 0 ƒ a (){}
a1 = 1;
console.log(window.a, a);
// 0 1
function a (){};
// 这里应该理解为赋值 a0 = a1
console.log(window.a, a);
// 1 1
a1 = 21;
console.log(window.a, a);
// 1 21
}
console.log(window.a, a);
// 即 console.log(a0, a0);
// 1 1
规范:
http://www.ecma-international...
另外 Safari 上的表现并不是这样的。
8 回答4.3k 阅读✓ 已解决
6 回答2.7k 阅读✓ 已解决
5 回答2.4k 阅读✓ 已解决
5 回答6.1k 阅读✓ 已解决
4 回答2.1k 阅读✓ 已解决
3 回答2.3k 阅读
4 回答2.6k 阅读✓ 已解决
首先要记住:函数声明置顶比变量声明置顶更优先
因为在预解析阶段变量只声明了,但未赋值,而函数不一样,它在预解析阶段就已经声明和赋值了,它的值就是函数这个对象
然后来看代码:
1、
var a = 0
:声明了一个变量a
,并赋值为0
2、看if里面代码;我们先就看
a=1
和function a(){}
3、
第一个console
;window.a
找的是全局的变量a
,在全局下已经声明有了a
,所以值为0
,后面的a
会现在if代码块
里查找,变量提升了,所以打印的是function a(){}4、执行到
a=1
;因为没有var
关键字,所以a
相当于一个全局变量,此时a
就会覆盖原来a
的值,变为1
;而if代码块里也直接找寻到名为a
的函数,所以将a
赋值为1,因此第二个console值为 0, 15、
第三个console
,此时已经赋过一次值,在打印,就是1, 16、
第四个console
,a=21
,在if代码块里查找,找到了函数名a
,将值赋给了这个函数对象;所以这次打印的是1,217、
第五个console
,就是打印全局的a,所以是1, 1以上就是我的理解,如果有错,欢迎指出,共同理解进步哈?