JS-函数的作用域和执行上下文

本文探讨了JavaScript的解释型与编译型特性,详细讲解了执行上下文、作用域链、变量对象、函数调用与执行上下文栈的关系,以及return语句的作用。特别关注了全局、函数和块级作用域,以及内存空间管理和作用域模型的动态性和静态性。

执行上下文

JS编译型语言

  • JS是一种具有函数优先的轻量级、解释型或即时编译型的编译语言
    • 解释型语言 在运行程序的时候才解析,每执行一段代码就翻译一段代码
    • 编译型语言 写的程序在执行之前,需要一个专门的编译过程,把所有程序编译成机器语言文件

JS 运行环境

  • JS 代码执行过程
    • JS引擎是一段一段地运行代码
    • JS代码执行时,会为当前代码创建相应的运行环境
  • JS 运行环境
    • 全局环境:代码运行起来后进入全局环境
    • 函数环境:函数被调用执行时,会进入当前函数中执行代码

执行上下文

  • 执行上下文
    • 可以理解为当前代码的运行环境
    • 作用是用来保存当前代码运行时所需要的数据
    • 在全局环境、函数环境中会创建执行上下文
  • 执行上下文栈
    • 执行上下文栈按照函数的调用顺序来管理执行上下文
    • 栈底永远是全局上下文,栈顶是当前正在执行的函数
    • 特点:先进后出
  • 每个执行上下文都有一个与之关联的变量对象和一个作用域链

生命周期

  • 当一个函数调用时,一个新的执行上下文就会被创建
  • 执行上下文的声明周期
    • 创建阶段
      • 生成变量对象
      • 建立作用域链
      • 确定 this 指向
    • 执行阶段
      • 变量赋值
      • 函数引用
      • 执行其他代码
    • 等待回收阶段

return 语句的作用

  • 返回值
    • 若只有return,返回undefined
  • 终止函数的执行

变量对象

变量对象

  • 变量对象
    • 变量对象是与执行上下文相关的数据作用域
    • 变量对象是与上下文关联的特殊对象,用于存储被定义在上下文中的变量和函数声明
  • 变量对象创建过程
    • 建立 arguments 对象
    • 检查当前上下文的函数声明
    • 检查当前上下文中的变量声明

作用域链

作用域

  • 作用域:是一套关于如何存储变量当中的值,并且能在之后对这个值进行访问修改的规则。
  • 作用域的作用
    • 作用域指定变量和函数的可访问范围
    • 作用域控制着变量和函数的可见性

作用域类型

  • 全局作用域
  • 函数作用域
  • 块作用域

全局作用域

  • 全局作用域
    • 在全局作用域下声明的变量叫做全局变量
    • 全局变量在全局下都可以使用
    • 全局作用域中无法访问到局部作用域中的变量
  • 创建方式
    • 在全局作用域下 var 声明的变量
    • 在函数内部,没有使用var 声明的变量
    • 使用 window 全局对象创建的属性和方法
      就是 window.xxx,有时也不用写 window

函数作用域

  • 函数作用域
    • 在函数作用于下声明的变量叫局部变量
    • 局部变量只在当前函数内部中使用
    • 局部作用域中可以访问到全局作用域中的变量
  • 创建方式
    • 在函数内部通过 var 声明的变量
    • 函数的形参
  • 块作用域
    • 任何一对 { } 中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,称之为块级作用域。

作用域模型

  • 词法作用域(静态性)
    • 由函数定义的书写位置决定的,与调用位置无关
    • 通过 new Function 创建的函数对象总是在全局作用域中执行
    var scope = "global";
    function checkScope() {
        var scope = "local";
        return new Function("return scope;");
    }
    console.log(checkScope()()); //global
    
  • 动态作用域 (动态性)
    • 由调用位置决定,不关心变量和函数定义的书写位置

[[scope]]

  • 虚拟属性,无法访问和修改
  • 函数创建时生成的属性,保存着这个函数所有父级执行上下文环境中的变量对象的集合
//复制后的函数与复制前的函数引用的是同一个 [ [ scope ] ] 属性
       var x = 10;
       function foo() {
           console.log(x);
       }
       foo(); // 10
       function fun() {
           var x = 20;
           var foo1 = foo;
           foo1(); // 10
       }
       fun();

内存空间管理

  • 若函数里面有两个对象,也是一个内存块
    var fun1, fun2;
     function foo() {
       var x = 10;
       //在全局生成的,生成以后不释放
       fun1 = function() {
         console.log(++x);
       };
       fun2 = function() {
         console.log(--x);
       };
     }
         foo();
     fun1(); // 11
     fun1(); // 12
     fun2(); // 11
     fun2(); //10
   	foo();
     fun1(); //11
   ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值