javascript的预解释

381 阅读2分钟
  • 什么是预解释(变量提声)

当浏览器开始解析JS代码的时候,首先看当前的运行环境(作用域)有没有带var和function,带var的变量会提前声明但是不会赋值,但是会带有一个默认值undefined,当代码执行过后才会复制;带function的会提前声明并且会立即赋值。

预解释需要注意的几个点

  • 预解释只看等号左面的变量,并不会看你的值是什么
  • 预解释只发生在当前作用域
  • 预解释的时候无论你的条件是否成立,都要把里面的var提前声明
  • return下面的代码仍然会被预解释,但是return后面的值即使你是一个函数也不会被预解释
  • 自执行函数不被预解释

先看下面的例子

    console.log(obj);//undefined
    console.log(num);//undefined
    var num = 12; //赋值
    console.log(num); //12
    var obj = {'name': 'tianxi', age: 30}; //对象类型
    console.log(obj);
    预解释只看等号左面的变量,并不会看你的值是什么
    function sum(num1, num2) { //当代码执行到这的时候,声明和赋值都已经结束,直接跳过
        function haha() {
        }; //我们的预解释只发生在当前作用域
        var total = 0;
        total = num1 + num2;
    }
  • 堆和栈

    -栈内存:提供一个让JS代码执行的环境,全局作用域和私有作用域都存储在这里。 -堆内存:是一个存储空间,放着所有的应用类型,需要存储的内容都在堆内存中,比如对象存储键值对,函数存储代码字符串;保存的都是一个地址

画图更容易理解

先把会预解释的全部提上来,是var的先不赋值,是function的立即赋值,当遇到function或者对象这种引用类型时,会开辟一个堆内存。

  • 预解释的时候各种情况

    • 1、无论条件是否成立,都会预解释
    console.log(total); //undefined
      if('total' in window){
          var total = 6;
      }
      console.log(total); //6,
    
    • 2、预解释的时候带var关键字只看等号左面,并不会看你的值是什么
     console.log(a)//undefined
      var a = function () {};
    
    • 3、自执行函数不被预解释
     !function (){
          var b = 0;
      }(
    
    • 4、return下面的代码仍然会被预解释,但是return后面的值即使你是一个函数也不会被预解释
    function fn(){
         console.log(num); //undefined
         return function (){
             console.log(num);
          }
         var num = 9;//return 下面的代码不执行,但是还会声明提前
      }
       fn();
    
  • 面试题

fn();//->2
    function fn(){
        console.log(1);  //虽然重复,但是提前,并且已经做过一遍
    }
    fn();//->2
    var fn = 12//代码执行到这的时候,我们原来的函数引用地址已经被破坏,并且把n赋值为12,
    fn();//=》10   前面已经有一个fn,不是函数所以报fn is not function
    function fn(){
        console.log(2);
    }
fn();//运行结果:2 2 error