变量作用域与内存(下)

js 变量作用域与内存(下)

🙌执行上下文与作用域

执行上下文简称上下文,变量或者函数的上下文决定了它可以访问那些数据,每一个上下文都有一个活动对象,上下文定义的变量和函数都存在与这个对象上,全局上下文也就是 window 对象。var 定义的全局变量都会成功为 window 的对象的属性和方法。当前上下文在其说有的代码执行完毕后会被销毁。

每一个函数都有自己的上下文,当执行流进入函数的时候,函数的上下文会被添加到全局上下文的栈上面,当这个函数执行完毕后,函数上下文会被弹出栈并将控制权返回给之前执行的上下文

在上下文中的代码执行中,会创建变量的作用域链,他决定了各级上下文中的代码在访问变量和函数的时序,作用域链中的下一个变量对象来自包含上一个上下文,在下一个对象来自下一个包含上下文,全局上下文始终是最后有一个变量对象

javascript 复制代码
var color = "blue";

function changecolor(){

  let authercolor = "red";

  function swapcolor(){

    let temp = authercolor;

    authercolor = color;

    color = temp;

    //这里可以访问 color authercolor temp

  }

  //这个可以访问 color authercolor 但访问不到temp

  swapcolor()

}

changecolor() //这里只能访问color

👀作用域链增强

上下文只要有全局上下文和函数上下文两种,某些语句会导致在作用域链的前端临时添加一个上下文,这个上下文在执行后会被删除

  • try/catch语句的catch块

  • with语句

对于with语句来说,会向作用域链最前端添加指定对象;对于catch而言会创建一个新的变量对象;

javascript 复制代码
function buildUrl(){

  let qs = "xxxxxx";

  with(location){

    var url = href + qs;

  }

  return val;

}

在上的代码中,with语句中会发现href没有定义,实际上with语句传入了lacaltion对象,而href变量也就是location.href,with语句在作用域链的前端添加了location活动对象,在变量搜索的时候会从location对象开始。在with语句var定义的变量会被当作函数上下文中的变量

✨js的垃圾回收

javascript是使用垃圾回收语言,也就是在代码的运行时环境管理内存,在js中只要是使用标记清理法来释放内存,垃圾回收在各个浏览器的执行频率有所不同

#####🐱‍👤🐱‍👤 标记清理法

当垃圾回收程序运行的时候会标记内存中的所有变量(标记的方法有很多种),然后在消除所有在上下文中的变量的标记,剩下的带有标记的变量就是需要清除的变量,因为在此之后的上下文已经访问不到了这些变量。

🐱‍🐉🐱‍🐉内存管理

🤔😆合理解除对象的引用
javascript 复制代码
function create(name){

  let lacal = new Object();

  lacal.name = name;

  return local

}

let global = create("xxx");

global = null

在上面的代码中,在调用函数create后赋值给global变量中,当这个变量不会再使用的时候需要将变量赋值为null,这样不会让变量立马被回收,但是会加快变量的回收时机,因为垃圾回收程序是周期性的执行,当垃圾回收程序代码检测到这个变量的引用为空,就会回收此变量。

🤳使用const和let声明

因为const 与 let 声明是块级作用域,函数上下文执行完毕后,会加快垃圾会回收,这与上一个的思路是一样的

🎂🌹内存泄露

意外的声明过多的全局变量容易造成内存泄漏,导致垃圾回收程序无法回收变量,

定时器一直引用着外部变量,导致变量无法回收

javascript 复制代码
let name = "djy";

setInterval(()=>{

  cansol.log(name);

},100);

上面代码定时器内部一直引用着name,垃圾回收程序不会回收name变量

闭包:

javascript 复制代码
let outher = function(){

  let name = "djy";

  return function(){

    return name;

}

这会导致分配给name的内存泄露,创建了一个内部闭包,只要auther函数存在就不能清理name,因为闭包一直引用着它

✨✨✨✨总结✨✨✨

对js的内存管理,变量更加熟悉,强力推荐这本书《javascript 高级程序设计》

相关推荐
SRET5 分钟前
Mineradio 沙盒隔离安装完全指南 | 一键安全运行 Electron 应用!!!
javascript·经验分享·安全·electron·aigc·音视频·ai编程
全栈前端老曹11 分钟前
【MongoDB】安全与权限管理 —— 用户认证、角色权限、SSL 加密
前端·javascript·数据库·安全·mongodb·nosql·ssl
free354 小时前
作用域链与 Environment:变量查找、遮蔽和赋值怎么实现
javascript
YHL4 小时前
🤖 Agent 智能体开发实战 · 第一课:Tool Use —— 让大模型自动干活
前端·javascript·人工智能
HUMHSX5 小时前
Vue 组件通信核心知识点梳理
javascript·vue.js·ecmascript
风止何安啊5 小时前
🚦 前端并发请求 “交通管制”:别让你的接口堵成早高峰
前端·javascript·面试
熊猫钓鱼>_>6 小时前
2026 前端的三场底层革命:当 Vue、React Native 和 Three.js 同时去掉中间层
前端·javascript·vue.js·react native·架构·webgl·three.js
名字还没想好☜6 小时前
React useEffect 依赖数组踩坑:闭包陷阱与清理函数
前端·javascript·react.js·react·useeffect
柒和远方7 小时前
LeetCode 4. 寻找两个正序数组的中位数 —— 二分划分的艺术
javascript·python·算法
默_笙7 小时前
😢 我被 JS 的 this 整不会了:同一个函数,换个“地区”调用,结果就不一样
javascript