美文网首页
JavaScript基础06- 作用域与预解析

JavaScript基础06- 作用域与预解析

作者: 释梦石 | 来源:发表于2020-08-25 00:06 被阅读0次

作用域

通俗来讲,作用域是一个变量或函数的作用范围。作用域在函数定义时,就已经确定了。目的是为了提高程序的可靠性,减少命名冲突。

作用域的分类

  1. 全局作用域
  2. 局部作用域(函数作用域)

根据作用域的不同,变量可以分为两类: 全局变量和局部变量

全局变量

  1. 在全局作用域下声明的变量,叫「全局变量」。在全局作用域的任何一地方,都可以访问这个变量。
  2. 在全局作用域下,使用 var 声明的变量是全局变量。
  3. 在函数内不使用 var 声明的变量也是全局变量(不建议这么用)。

局部变量

  1. 定义在函数作用域的变量,叫「局部变量」。
  2. 在函数内部,使用 var 声明的变量是局部变量。
  3. 函数的形参也是属于局部变量。
    从执行效率来看全局变量和局部变量:
  4. 全局变量:只有浏览器关闭时才会被销毁,比较占内存。
  5. 局部变量:当其所在的代码块运行结束后,就会被销毁,比较节约内存空间。

作用域链

只有函数可以制造作用域结构, 那么只要是代码,就至少有一个作用域, 即全局作用域。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。将这样的所有的作用域列出来,可以有一个结构: 函数内指向函数外的链式结构。就称作作用域链。

  1. 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用(就近原则)。如果没有则向上一级作用域中寻找,直到找到全局作用域;如果全局作用域中依然没有找到,则会报错。
  2. 在函数中要访问全局变量可以使用window对象。(比如说,全局作用域和函数作用域都定义了变量a,如果想访问全局变量,可以使用window.a)
  3. 全局作用域在页面打开时创建,在页面关闭时销毁。
  4. 在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口,由浏览器创建,我们可以直接使用。全局作用域创建的变量都会作为window对象的属性保存。比如在全局作用域内写 var a = 100,这里的 a 等价于 window.a。创建的函数都会作为window对象的方法保存。

预解析

JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的。JavaScript解析器执行JavaScript代码的时候,分为两个过程:预解析过程和代码执行过程

预解析过程

  1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
  2. 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
  3. 先提升var,在提升function

变量的声明提前

使用var关键字声明的变量( 比如 var a = 1),会在所有的代码执行之前被声明(但是不会赋值),但是如果声明变量时不是用var关键字(比如直接写a = 1),则变量不会被声明提前。
所以,既然JS中存在变量提升的现象,那么,在实战开发中,为了避免出错,建议先声明一个变量,然后再使用这个变量。

函数的声明提前

使用函数声明的形式创建的函数function foo(){},会被声明提前。也就是说,整个函数会在所有的代码执行之前就被创建完成。所以,在代码顺序里,我们可以先调用函数,再定义函数。

 fn1();  // 虽然 函数 fn1 的定义是在后面,但是因为被提前声明了, 所以此处可以调用函数
    function fn1() {
        console.log('上边儿调用的时候,函数声明已经被提前了');
    }

使用函数表达式创建的函数var foo = function(){},不会被声明提前,所以不能在声明前调用。

函数表达式

函数作用域

  1. 函数中,使用var关键字声明的变量,会在函数中所有的代码执行之前被声明。
  2. 函数中,没有var声明的变量都是全局变量,而且并不会提前声明。

注意,定义形参就相当于在函数作用域中声明了变量。

 function fun(e) { // 这个函数中,因为有了形参 e,此时就相当于在函数内部的第一行代码里,写了 var e;
        console.log(e);
    }

函数预编译步骤

预编译四部曲:

  1. 函数在运行的瞬间,生成一个执行期上下文 (Active Object),简称AO;
  2. 分析参数
    2.1 函数接收形式参数,添加到AO的属性,并且这个时候值为undefine,例如AO.age=undefined;
    2.2 接收实参,添加到AO的属性,覆盖之前的undefined;
  3. 分析变量声明,如var age;或var age=23;
    3.1 如果上一步分析参数中AO还没有age属性,则添加AO属性为undefined,即AO.age=undefined;
    3.2 如果AO上面已经有age属性了,则不作任何修改;
  4. 分析函数的声明,如果有function age(){};把函数赋给AO.age ,覆盖上一步分析的值;
函数预编译

执行期上下文:
当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁

相关文章

  • JavaScript基础06- 作用域与预解析

    作用域 通俗来讲,作用域是一个变量或函数的作用范围。作用域在函数定义时,就已经确定了。目的是为了提高程序的可靠性,...

  • Javascript 基础 And 进阶

    Javascript 基础 And 进阶 知识点: 原型链 this指向 作用域和预解析 new关键字 闭包 DO...

  • 作用域、作用域链

    作用域 在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。 作用域下浏览器的操作 预解析(找v...

  • JavaScript中的内存释放

    一、如何查找上级作用域 在 JavaScript中的预解析 ,有讲到作用域链的概念,本次在正式讲JavaScrip...

  • JavaScript基础--变量作用域和预解析

    作用域 在JavaScript中{}外面的作用域, 我们称之为全局作用域 在JavaScript中函数后面{}中的...

  • JavaScript作用域和预解析

    作用域链 默认情况下全局作用域, 我们称之为0级作用域 只要定义一个函数就会再开启一个作用域 如果该函数是在全局作...

  • JavaScript作用域和预解析

    作用域 JavaScript中也有作用域的概念 相同作用域内不能有同名的变量和函数, 不同作用域内可以有同名的变量...

  • JS基础:作用域

    一、作用域概念-预解析规则、表达式 作用域: 域:空间,范围,区域……作用:读,写 浏览器——JS解析器: 在浏览...

  • JS基础---05作用域

    JavaScript基础 1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作...

  • JavaScript作用域学习笔记

    @(JS技巧)[JavaScript, 作用域] JavaScript作用域学习笔记 概念: 作用域就是变量与函数...

网友评论

      本文标题:JavaScript基础06- 作用域与预解析

      本文链接:https://www.haomeiwen.com/subject/dakkjktx.html