0

0

讲解 JS 内存管理机制及验证

coldplay.xixi

coldplay.xixi

发布时间:2020-12-30 17:34:41

|

3026人浏览过

|

来源于segmentfault

转载

javascript栏目介绍内存管理机制及验证

讲解 JS 内存管理机制及验证

推荐(免费):JavaScript(视频)

作用域

JavaScript 的变量被作用域所限制,如果超出了作用域,那么变量就没有办法再被使用,这样做的优点是:

  • 可以避免当前的变量转为全局变量
  • 有效限制变量的作用区域

而变量作用域也会按照声明方式的不同,产生不同的作用域:

  • 未声明:全局变量
  • var 声明:作用域在 函数
  • letconst 声明:作用域在 {}

var 声明的变量

在函数内声明的变量其作用域会被限制在该函数的调用栈中,在外部无法直接得到该作用域内的变量。下面的例子中, fn 函数内的变量在全局下是没有办法查看的。

function fn() {
  var a = 1;
}
fn();
console.log(a); // 无法得到 fn 函数內的 a 变量

所以常用 "立即函数" 来限制变量的作用域,主要是避免全局变量的产生。

(function() {
  var b = 1;
})();
console.log(b); // 无法得到 fn 函数內的 b 变量

let、const 声明的变量

ES6 之后所新增的letconst 作用域则与过去不同,改用 {} 作为作限制用域的方式,这让 for 循环及部分语法避免产生多余的变量来影响作用域。

var 不同的是 const 所定义的变量作用域被限制在 {} 中。所以这个例子中的变量 c 可在外部得到值,d 则无法取到。

{
  var c = 1;
  const d = 1;
}
console.log(c); // 1
console.log(d); // Uncaught ReferenceError: d is not defined,无法取到变量 d

内存管理机制

每当我们新增一个变量时,在内存中就会占用一个位置来保存它的值,以便在程序后续运行时可以多次使用。

下面的代码会在内存中开辟一个 a 的空间来存储数字 1 的值。

var a = 1

流程如下:

  1. 开辟一个内存空间来存放变量  a ,不过这时还没有赋值(原因可参考:Hoisting)

a1f73427d490ec550e79ac06b2abdb8.png

  1. a 赋值。

2a2c245dd1d9d9e210bd692708380d7.png

php商城系统
php商城系统

PHP商城系统是国内功能优秀的网上商城系统,同时也是一个商业的PHP开发框架,有多套免费模版,强大的后台管理功能,专业的网上商城系统解决方案,快速建设网上购物商城、数码商城、手机商城、办公用品商城等网站。 php商城系统v3.0 rc6升级 1、主要修复用户使用中出现的js未加载完报错问题,后台整改、以及后台栏目的全新部署、更利于用户体验。 2、扩展出,更多系统内部的功能,以便用户能够迅速找到需

下载

所有的变量都会占用内存空间,除此之外对象、数组的属性以及函数参数等也会用相同的概念进行占用。调用一个函数时,每一个函数的作用域也都会反复的进行内存占用。随着应用程序越来越复杂的情况下,如果持续的占用内存而没有进行适当的释放,那么内存可能会被耗尽。

JavaScript 引擎具有内存回收的机制,会释放不再使用的变量内存,其基本概念为:当没有任何的引用指向它时就会释放内存。

来自MDN:collectible if there are zero references pointing to it.

内存释放的验证

下面用一个例子来说明及验证内存释放的机制,首先用一段函数来产生一个非常长的字符串,长字符串会占用大量的内存空间。

在调用 randomString 函数后会返回一个很长的字串:

function randomString(length) {
  var result = '';
  var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  var charactersLength = characters.length;
  for (var i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}

案例一:使变量维持在可引用的状态(不会释放内存)

定义一个全局变量 demoData,这个变量会持续维持可被引用的状态。

var demoData = []; // 全局变量
function getData() {
  for (let i = 0; i < 1000; i++) {
    demoData.push(randomString(5000))
  }
}
getData()
console.log(demoData); // 可引用 demoData 值

执行这段代码后,进入 Chrome DevTools 中的 Memory 页,这个功能可以得到当前页面所占用的内存状况。接下来点击 "Take snapshot" 按钮。

671a00ef74c97d9e614b136acc82cee.png

可以看到目前执行完这段代码后占用了 6.2MB 的内存空间(注意:任何浏览器环境和插件都会影响所占用的内存状态)。

0b4169d1a88847a1dc786497971be80.png

案例二:使变量无法再次被引用(执行后释放内存)

限制变量的作用域,使变量无法再被外部引用。

此段代码依然会执行这个函数,也会将值赋值给变量,但外部无法再次引用 demoData 的值。

function getData() {
  var demoData = []; // 局部变量
  for (var i = 0; i < 1000; i++) {
    demoData.push(randomString(5000))
  }
}
getData();

然后回到 Memory 页点击 "Take snapshot" 重新取得内存的状态,接下来会得到与前面不同的结果,这次只占用了 1.2MB 的内存(其中 5MB 被释放掉了)

0beb59b1b77a6ba65399e8633e59f23.png

总结

通过前面的例子,我们知道了作用域以及内存之间的关系,而内存管理也是前端打工人必须要掌握的知识(除了控制内存的使用大小,还需在必要时保留而不被释放)。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

556

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

374

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

754

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

477

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

434

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

1011

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

658

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

553

2023.09.20

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

19

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

相关下载

更多

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.9万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.3万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号