首页 > 系统相关 >第三篇 作用域、作用域链、执行上下文、函数、内存泄漏和垃圾回收

第三篇 作用域、作用域链、执行上下文、函数、内存泄漏和垃圾回收

时间:2023-03-28 14:11:23浏览次数:55  
标签:执行 第三篇 函数 作用域 内存 上下文 变量

1、作用域

作用域表示当前的执行上下文,值和表达式在其中可见或可被访问到的上下文。作用域决定了代码区块中变量和其他资源的可见性。

1、全局作用域

   在代码中任何地方都能访问到的对象,拥有全局作用域。
   
   window对象的属性、方法
   
   定义在最外层的变量、函数、对象
   
   未定义直接赋值的变量
   
2、局部作用域

   局部作用域相当于函数作用域,指函数内部的空间。函数内部的变量,在外部无法访问。
   
3、块级作用域

   块级作用域指被大括号{}包裹在内的部分。比如,如果if语句使用{}包裹,就生成了一个块级作用域。

2、作用域链

当在某个函数的内部作用域中查找某个变量时,如果没有找到就会到他的父级作用域中查找,如果父级也没找到就会接着一层一层的向上寻找,直到找到全局作用域还是没找到的话,就结束寻找,认定为变量未定义。这种一层一层的作用域嵌套关系,就是作用域链。

作用域存在的意义
   
  变量隔离,不同作用域下同名变量不会出现冲突。

3、函数

函数定义
1、函数申明

   函数申明会被提升

2、函数表达式

   不能提升

3、箭头函数

   没有 this 和 arguments

4、function 构造器

   JavaScript 中每个函数是 Function 对象,所以要定义函数,可以直接调用 Function 对象的构造器。
   
   let sum = new Function('param1', 'param2', 'return param1 + param2');

5、Generator 函数

   Generator函数会在每个请求的基础上生成多个值,并在这些请求之

4、函数重载

1、是函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数

2、重载函数通常用来声明一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。

 js 因为后面定义的同名函数会覆盖前面的函数,所以 js没有函数重载

5、执行上下文

执行上下文就是一个评估和执行 JavaScript 代码的环境的抽象概念。通俗地说,就是每当 Javascript 代码在运行的时候,它都是在执行上下文中运行。

JavaScript 中有三种执行上下文

1、全局执行上下文 

2、函数执行上下文

3、Eval 函数执行上下文

执行上下文的生命周期包括三个阶段:创建阶段 → 执行阶段 → 回收阶段

在 JavaScript 代码执行前,执行上下文将经历创建阶段。在创建阶段会发生三件事:

  this 值的决定,即我们所熟知的 This 绑定。

  创建词法环境组件

  创建变量环境组件
  
this的绑定

   在全局执行上下文中,this 的值指向全局对象。(在浏览器中,this引用 Window 对象)。
  
  在函数执行上下文中,this 的值取决于该函数是如何被调用的。
  
  如果它被一个引用对象调用,那么 this 会被设置成那个对象,否则 this 的值被设置为全局对象或者 undefined(在严格模式下)。
  
  
注意: 

作用域就是一个独立的区域,它可以让变量不会向外暴露出去。作用域最大的用处就是隔离变量。内层作用域可以访问外层作用域。一个作用域下可能包含若干个执行上下文。 

执行上下文创建阶段时,引擎检查代码找出变量和函数声明,虽然函数声明完全存储在环境中,但是变量最初设置为 undefined(var 情况下),但未初始化(let 和 const 情况下)。

所以可以在声明之前访问 var 定义的变量(虽然是 undefined),但是在声明之前访问 let 和 const 的变量会得到一个引用错误。

总结一下:

  JavaScript 属于解释型语言,JavaScript 的执行分为解释和执行两个阶段,这两个阶段所做的事并不一样
  
  解释阶段:

    词法分析
   
    语法分析
   
    作用域规则确定
   
  执行阶段:

    创建执行上下文
    
    执行函数代码
    
    垃圾回收

6、内存泄漏与垃圾回收

内存泄漏
 1、程序未能释放那些已经不再使用的内存,造成内存的浪费。
 
 2、一般是堆区内存泄漏,栈区不会泄漏。
 
 3、基本类型的值存在内存中,被保存在栈内存中,引用类型的值是对象,保存在堆内存中。所以对象、数组之类的,才会发生内存泄漏。
 
 哪些情况会出现内存泄漏:
 
 1、意外的全局变量
 
   当我们使用默认(不通过var申明)绑定定义变量,this会指向全局。
   
 2、被遗忘的定时器和回调函数
 
    当不需要setInterval或者setTimeout时,定时器没有被clear,定时器的回调函数以及内部依赖的变量都不能被回收,造成内存泄漏。
    
 3、闭包
 
    闭包可以维持函数内局部变量,使其得不到释放,造成内存泄漏。
    
 如何减少内存泄漏:
 
 1、减少不必要的全局变量,使用严格模式避免意外创建全局变量,严格模式下this指向undefined。
 
 2、在你使用完数据后,及时解除引用(闭包中的变量,dom引用,定时器清除)。
 
 3、组织好你的逻辑,避免死循环等造成浏览器卡顿,崩溃的问题。
垃圾回收机制

原理:按照固定的时间间隔,周期性的找出不再继续使用的变量,然后释放其占用的内存。

意义:在不需要字符串、对象的时候,需要释放其所占用的内存,否则将会消耗完系统中所有可用的内存,造成系统崩溃,这就是垃圾回收机制所存在的意义。

方法:
 
  1、标记清除
  
    当变量进入环境时(例如在函数中声明一个变量),将这个变量标记为“进入环境”,当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。
    
  2、引用计数 【被废弃的垃圾收集策略】

标签:执行,第三篇,函数,作用域,内存,上下文,变量
From: https://www.cnblogs.com/caix-1987/p/17264957.html

相关文章

  • 什么是上下文切换?
    多线程编程中一般线程的个数都大于CPU核心的个数,而一个CPU核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU采取的策略是为每个线程分配时间片并......
  • selenium的作用域及解决登录验证问题
    一、selenium的作用域切换selenium在处理元素时遇见新窗口、网页嵌套网页、网页的原生弹窗,无法进行直接处理作用域里元素的内容,需要通过切换作用域来处理此类问题。selen......
  • 第4章 —— 变量、作用域与内存
    4.1原始值和引用值原始值是最简单的数据,引用值是存储在内存中的对象。保存原始值的变量是按值访问的,引用值的变量是按引用访问的。区别:原始值大小固定,保存在栈内存上;......
  • flask-上下文对象-手动开启上下文
    1、请求上下文requestcontext 总结:请求上下文:request:获取请求信息,比如表单参数、查询字符串等session:操作用户会话信息,session['key']=value.session.get('key')......
  • Laravel 中 scope 查询作用域
    阅读目录一、查询作用域1.1全局作用域1编写全局作用域2匿名全局作用域3取消全局作用域1.2本地作用域1编写本地作用域2动态作用域二、应用示例三、简单演示理解示例一......
  • 一统天下 flutter - widget Builder: Builder - 在指定的位置构造上下文
    一统天下flutterhttps://github.com/webabcd/flutter_demo作者webabcd一统天下flutter-widgetBuilder:Builder-在指定的位置构造上下文示例如下:lib\widge......
  • 第六天(SpringBoot基础篇第三篇)
    一、Thymeleaf模板1.介绍Thymeleaf是用来开发Web和独立环境项目的现代服务器端Java模板引擎。Thymeleaf的主要目标是为您的开发工作流程带来优雅的自然模板-HTML。......
  • 第六天(springBoot基础第三篇)
    一、Thymeleaf模板1.介绍Thymeleaf是用来开发Web和独立环境项目的现代服务器端Java模板引擎。Thymeleaf的主要目标是为您的开发工作流程带来优雅的自然模板-HTML。......
  • jenkins-groovy里的cd命令没有上下文关系
    场景:需要cd到某一个文件夹,再执行py文件时,发现cd命令没有效果例如:bat"cdtest"      bat"pythontest.py"第一个命令bat"cdtest"执行您期望的操作。但是......
  • 作用域和构造器
    1.作用域上部分承接course-322.作用域注意事项2372.1例publicclassTest33{publicstaticvoidmain(String[]args){Tt1=newT();//属性生命周期......