js域解析问题-if中声明函数

在if中声明函数(我知道这样好像会有问题),但是我看视频中老师这样子写,
alert(fn1);在chrome得到的是fn1整个函数,在火狐中得到的是fn1未定义错误。
可是我自己弄出来都是undefined,求大神告知原理~

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

    <script type="text/javascript">

        alert(fn1);  //undefined

        if(true) {
            var a = 1;
            function fn1() {
                alert(123);
            }
        }


    </script>
</body>
</html>
 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

    <script type="text/javascript">

        alert(fn1);//undefined

        if(true) {
            var a = 1;

            // function fn1() {
            //     alert(123);
            // }

            var fn1 = function() {
                alert(123)
            }

            // alert(fn1);  // function fn1() {
                            //     alert(123);
                            // }
        }
    </script>
</body>
</html>

函数的写法,你写的是申明式的函数,我将他换成表达式的写法。你会理解,这边你在函数为创建前,打印函数名,js中有变量名提升,函数提升,但是内容不会提升,所以一开始是 undefined,你在函数下面打印则是整个函数。

 <script type="text/javascript">
        alert(fn1);  //undefined
        if(true) {
            var a = 1;
            function fn1() {
                alert(123);
            }
            alert(fn1);
        }
            alert(fn1);
    </script>

首先 if里不是声明函数 而是判断条件 true 意思就是 条件为真时 执行if里面的语句

下来 你的 undefined 是没错的执行第一个alert 时 程序从上到下还没有读取到fn1函数 所以是undefined

当你把alert放到fn1函数下面输出时 就会输出整个函数
参考以上代码

js是从上往下执行的,“alert(fn1)”执行这句时还没定义呢

涉及到JS解析过程中 变量提升。 声明式的函数(fn) > 声明式的变量 (var)

将你的代码分解,变成

alert(fn1);  //undefined

if(true) {
    var a = 1;
    var fn1 = function () {  //修改了此处
        alert(123);
    }
    alert(fn1);
}

alert(fn1);

再进行变量提升

var fn1;     //修改了此处
alert(fn1);  //undefined

if(true) {
    var a = 1;
    fn1 = function () {   //修改了此处
        alert(123);
    }
    alert(fn1);
}

alert(fn1);

这里涉及到一个历史遗留的问题——在ES5的规范中,函数声明不允许在块级作用域下声明,但各大浏览器出于兼容性的考虑,都没有遵守这个规范,函数有自己的行为方式——在块级作用域下,函数体是无法被预编译进去的。因为只有在执行阶段代码执行到 fn1 = function() { // ... } 这一句的时候,fn1才是一个函数,其他时候都是undefined。