学无止境,学海无涯

最近有朋友分享了道题,发现挺有意思的,分享大家了解一下:

(不足之处,请见谅!欢迎指正)

题目如下:

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.学无止境,不要轻易谈“精通”!!!!

原文地址:https://www.cnblogs.com/meijifu/p/12706957.html