zoukankan      html  css  js  c++  java
  • JavaScript作用域-声明提升(个人总结)

    声明提升(hoisting)分为变量声明提升和函数声明提升。声明从它们在代码中出现的位置被“移动”到最上面的过程,被称作声明提升。每个作用域都会有声明提升。

    在介绍作用域的内部原理时有提过,引擎在解释JS代码前首先进行编译,编译过程中会找到所有的声明,并用合适的作用域将它们关联起来。

    var a = 1;说明,这行代码包含了两步操作:var aa = 1。定义声明是在编译阶段进行的,赋值操作是在执行阶段进行的。

    // 示例1
    var a = 1;
    var a;
    console.log(a) // 1;
    
    // 示例2
    console.log(a) // undefined
    var a = 1;
    //等价于
    var a;
    console.log(a);
    a = 1;
    

    上面两个示例的奇怪行为,如果从声明提升的角度去看就很好理解了。

    示例1声明了两次变量a,它们都在编译阶段完成声明,JS允许声明同名变量,到了执行代码时,对a进行赋值操作,执行到第3不自然打印结果就是1。

    示例2也是同理,声明完成后a的值默认是undefined,到了执行阶段,赋值操作是在打印操作前完成的,所以结果就是undefined。

    注意: 每个作用域都会进行声明提升。

    console.log(a);
    var a = 1;
    function foo() {
      console.log(b);
      var b = 2;
      function foo2() {
       console.log(c);
       var c = 3;
      }
      foo2();
    }
    foo(); // undefined undefined undefined
    

    声明提升后是下面这样

    var a;
    console.log(a);
    a = 1;
    function foo() {
      var b;
      console.log(b);
      b = 2;
      function foo2() {
       var c;
       console.log(c);
       c = 3;
      }
      foo2();
    }
    foo(); // undefined undefined undefined
    

    函数声明提升

    // 提升前
    foo();
    function foo(){
      console.log(1);//1
    }
    
    // 提升后
    function foo(){
      console.log(1);// 1
    }
    foo();
    

    函数的调用在函数声明前也可以正常执行,就是因为函数声明提升的原因。

    函数声明可以提升,但是函数表达式不会提升。

    foo();
    var foo = function() {
      console.log(1); // foo is not a function
    }
    
    // 等价于
    var foo;
    foo();
    foo = function() {
      console.log(1); // foo is not a function
    }
    

    函数覆盖

    既然函数声明和变量声明都会提升,如果出现了同名的函数或变量,谁的优先级更高呢?以下是我个人总结的一套简单的记忆规则,仅供参考。

    把函数的权重默认为1,只声明未赋值的变量权重为1,声明且赋值的变量权重为2。高权重覆盖低权重,同权重后者覆盖前者。

    // 测试1 权重相等,后者覆盖前者
    var a;
    function a() {};
    console.log(a); function a(){}'
    
    // 测试2 变量权重大于函数,输出变量值
    var a = 1;
    function a(){}
    console.log(a);//1
    
    // 测试3 第一行权重大于第二行,输出1
    var a = 1;
    var a;
    console.log(a);//1
    
    // 测试4 权重相等,后者覆盖前者
    a();//2
    function a(){
      console.log(1);
    }
    function a(){
      console.log(2);
    }
    

    养成良好的开发习惯,避免在同一作用域中定义同名的变量或函数。

  • 相关阅读:
    ArcSDE 10.1安装、配置、连接 (SQL Server 2008)
    ASP.NET MVC 音乐商店
    ASP.NET MVC 音乐商店
    一些Web开发工具
    Apache 2 频率限制模块
    零起步高性能PHP框架 Phalcon 实战
    零配置Ubuntu下Wordpress安装
    零起步的Hadoop实践日记(hbase in action)
    零起步的Hadoop实践日记(hive in action)
    零起步的Hadoop实践日记(内存设置调整)
  • 原文地址:https://www.cnblogs.com/wjlbk/p/11839349.html
Copyright © 2011-2022 走看看