js彻底搞明白预解析

1、介绍

预解析,笔试常考的一个东西,前几天,群友发了个题目,确实有意思

JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析和代码执行。

  • 预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明(匿名函数没有function声明,所以不会提升)的变量在内存中进行提前声明或者定义。
  • 代码执行: 从上到下执行JS语句。

预解析也叫做变量、函数提升。
变量提升(变量预解析): 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。
函数提升: 函数的声明会被提升到当前作用域的最上面,但是不会调用函数

2、小试牛刀

function f1() {
        var a = b = c = 9;
        console.log(a);
        console.log(b);
        console.log(c);
    }
f1();
console.log(c);
console.log(b);
console.log(a);
console.log(window);
// 结果为 9 9 9 9 9 报错
// var a=b=c=9 其实 是 var a  , a=b=c=9 ,  
// 又因为 没有定义 b、c ,而是 直接赋值,默认会在 window 里面显示
        // 第2个 测试
        console.log(a)//undefined:带var变量预解析时存在提升
        var a = 0;
        console.log(a);//0
        // 其实它的代码执行顺序是 下面这样
        /* 
        var a 
        console.log(a)
        a = 0
        console.log(a)
        */

        console.log('第三个测试————————————————————————————');
        (function () {
            // 函数名 和 变量名 重名的时候,函数的优先级更高,定义变量并不会执行

            console.log(number); // 这里输出的其实是  这个函数
            var number = '我是变量number' // 这里 给number 重新赋值了
            function number() {
                console.log('我是函数');
            }
            console.log(number); // 所以这里输出的是 字符串变量
        })()
        /*
        function number(){console.log('我是函数');}
        console.log(number);
        number = '我是变量number'
        console.log(number);
        */


        console.log('第4个测试————————————————————————————');
        (function () {
            fn(11, 22); //报错:fn is not a function, 
            var fn = function (a, b) {
                return a + b;
            }
            //这个函数定义的方式是:函数表达式定义,在预解析时这个函数不会整体提升,
            //只是提升了 var fn = undefined,此时当函数调用,肯定就会报错
        })()

        console.log('第5个测试————————————————————————————');
        alert(a); //1. undefined
        var a = 0;
        alert(a); //2. 0

        function fn() {
            alert(a);
            a = 1;
            alert(a);
        } //函数在预解析提升时,如果函数重名,下边的会覆盖掉上边的,所以这函数失效
        fn()

        function fn() {
            alert(a); //3. undefined
            var a = 2;
            alert(a++); //4. 2:++在前,先赋值后运算,++在后,先运算再赋值,所以这里还是输出0,但a再后面已经变成1
        }

        alert(a); //5. 0:函数里的a带var,不影响全局的a

总结

  1. 函数的优先级高于变量的 预解析优先级
  2. 函数名 和 变量名 重名的时候,函数的优先级更高,定义变量并不会执行
  3. 函数在预解析提升时,如果函数重名,下边的会覆盖掉上边的

更详细的题目详解可以点击我

你可能感兴趣的:(js,js)