zoukankan      html  css  js  c++  java
  • JavaScript的作用域和变量提升

      看了众多的书籍和文章后,决定自己来写一遍关于作用域的知识点来巩固一下。

    作用域

      作用域在编程语言中,它是控制着变量与参数的可访问性和生命周期。

      作用域这个东西呢,可以假设它是一个采集工人,专注于收集和维护所有声明的标识符(变量),并且将标识符组成一系列的查询,并实现一套规则来管理标识符,确定执行环境(执行上下文)对标识符的使用权限。

    function foo () {
      var a = 1, b = 3;
    console.log(c) // 报错,变量c没有定义,父级函数不能获取子函数中的变量 // a => 1, b => 3
    function bar () { var c = 5, d = 7; a += b + c; // 可访问父级函数的a,b变量,并修改变量a的值 } // a => 1, b => 3 bar();
    // a => 9, b => } foo();

     

    块级作用域

      在JS函数中的var声明,其作用域是函数体的全部,在ES6之前并没有块级作用域的说法,在ES5中只有全局作用域和函数作用域。

      大多数像C语言的语言都拥有块级作用域,就是在一个代码块中(在一对花括号中的语句)定义的所有变量在代码块的外部是不可访问的,定义在代码块中的变量会在代码块执行完毕后会释放掉。

      在ES6中的新特性:let、const提供了块级作用域。

    if (true) {
      let a = 1;   
    }
    console.log(a)// Uncaught ReferenceError: a is not defined

    变量提升(Hoisting)

      直觉上会认为JavaScript代码在执行时是由上到下一行一行执行的。但实际上并不完全正确,有一种特殊情况会导致这个假设是错误的。

      考虑下面的代码

    a = 2;
    var a;
    console.log(a) // a => 2

      这种写法固然是不推荐的,但它却正确地输出出来,到底是为什么呢。

      再看看一下代码

    console.log(a) // a => undefined
    var a = 2

      搞明白这个问题,要了解引擎和编译器的机制。

      引擎在解释JavaSript代码之前首先会对其进行编译,编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。

      因此,正确的思路是:在编译的时候,变量和函数在内的所有声明都会在任何代码被执行之前被处理。

      当然,用ES6中的let就不会出现这个问题了,科科~

      

  • 相关阅读:
    Linux安装Oracle 10g
    Linux安装Oracle 10g
    如何利用BI实现人力资源可视化管理
    mongdb修改密码
    如何利用BI实现人力资源可视化管理
    jquery获取浏览器和屏幕的高度和宽度
    perl概述
    'CheckLicensesAndNotify' has encountered a problem.
    Caused by: java.sql.SQLException: The MySQL server is running with the --read-only option so it cann
    Caused by: java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Tim
  • 原文地址:https://www.cnblogs.com/ChivanTam/p/7322698.html
Copyright © 2011-2022 走看看