最近有朋友分享了道题,发现挺有意思的,分享大家了解一下:
(不足之处,请见谅!欢迎指正)
题目如下:
var a = 0; if (true) { a = 1; function a() {return '520'} a = 21; console.log(a); } console.log(a);
1.我第一反应是考虑变量提升,即代码等价于:
function a() {return '520'} var a = 0; if (true) { a = 1; a = 21; console.log(a); //21 } console.log(a); //21
接着又想到把函数声明写在判断语句中, 如果{ } 被看做代码块(块级作用域),那么函数的声明就在代码块内做提升,即代码等价于:
var a = 0; if (true) { function a() {return '520'} a = 1; a = 21; console.log(a); //21 } console.log(a); //0
然而实际的结果却感觉不是唯一的情况:
其中IE(5-10)版本浏览器的结果是:
21 21 //以上打印结果为IE浏览器5-10版本。
接着到了IE11 和 最新的 edge浏览器结果是:
21 function a() {return '520'} //以上打印结果为IE浏览器第11版本和edge浏览器。
结果来看,IE11以及edge浏览器认为, 函数声明为全局, 并且, 函数也没有进行提升, 而是把它当成了表达式处理,因此, 代码等价于:
var a = 0; if (true) { let a1 = 1; window.a = function() {return '520'} a1 = 21; console.log(a1); //21 } console.log(a); // function a() {return '520'}
接着我又对比了谷歌和火狐浏览器(并没有去一个个版本尝试),结果如下:
21 1 //以上打印结果为chrome浏览器 和火狐浏览器
可看出:谷歌浏览器跟火狐都认为, 直到出现了函数声明, 变量a才出现了局部作用,同时函数依然被当成了表达式, 而不是一个声明,即代码等价于:
var a = 0; if (true) { a = 1; let a1 = function() {return '520'} a1 = 21; console.log(a1); //21 } console.log(a); // 1
总结:
当函数被声明在判断语句内部时,所有浏览器都把 函数声明 当成了表达式(赋值声明),并且在对于是否应看作是全局声明, 也存在分歧异议,并没有统一标准。
结论:
1.永远不要把函数定义在条件判断中!!!!!
2.学无止境,不要轻易谈“精通”!!!!