避免内存泄漏/使用 Javascript

2023-11-22

我是 jQuery 的新手。我有点困惑这是否正常或可能导致内存泄漏?

代码如下:在某些日期过滤器上为每个新值调用此方法

function preapreTooltip(chart) {
    var tickLength = chart.xAxis[0].tickPositions.length,
        ticks = chart.xAxis[0].ticks,
        tickPositions = chart.xAxis[0].tickPositions;
    for ( var iCntr = 0; iCntr < tickLength; iCntr++) {
         var tickVal = tickPositions[iCntr];

    //.label or .mark or both
    (function(tickVal) { // Is this good practice to call function like this?
        ticks[tickVal].label
        .on('mouseover', function(event) { // Is this good practice to call function like this?
            var label = '', labelCnt=0;
            $(chart.series).each(function(nCntr, series) {
                //business logic for each series
            });

           // calling method to show values in a popup
        });

        ticks[tickVal].label.on('mouseout', function(event) { // Is this good practice to call function like this?
            try {
                hideWrapper(); // hides popup
            } catch (e) {
            // do nothing
            }
        });

    })(tickVal);
  }
}

虽然在编写大型纯 JavaScript 项目时需要避免一些特定于浏览器的问题,但在使用 jQuery 等库时,应该假设该库的设计可以帮助您避免这些问题。然而,考虑到内存泄漏相当难以追踪,并且特定浏览器的每个不同版本的行为可能有所不同 - 知道如何一般性地避免内存泄漏比具体地了解要好得多:

  1. 如果您的代码被迭代多次,请确保您正在使用的变量可以被丢弃垃圾收集,并且不受闭包引用的束缚。
  2. 如果您的代码正在处理大型数据结构,请确保您有一种删除或取消数据的方法。
  3. 如果您的代码构造了许多对象、函数和事件侦听器 - 最好也包含一些解构性代码。
  4. 尽量避免将 javascript 对象或函数作为属性直接附加到元素 - 即element.onclick = function(){}.
  5. 如果有疑问,请务必在代码完成后进行整理。

您似乎认为调用函数的方式会对泄漏产生影响,但是这些函数的内容总是更有可能导致问题。

对于上面的代码,我唯一的建议是:

  1. 每当使用事件侦听器时,都会尝试找到一种重用函数的方法,而不是为每个元素创建一个函数。这可以通过使用来实现事件委托 (将事件捕获到祖先/父级并将反应委托给event.target),或者编写一个单一的通用函数来以相对方式处理元素,通常是相对于this or $(this).

  2. 当需要创建许多事件处理程序时,通常最好将这些事件侦听器存储为命名函数,以便您可以在完成后再次删除它们。这意味着避免像您一样使用匿名函数。但是,如果您知道只有您的代码处理 DOM,则可以回退到使用$(elements).unbind('click')删除所有点击处理程序(匿名与否)使用 jQuery 将其应用于所选元素。然而,如果您确实使用后一种方法,那么使用 jQuery 的事件命名空间功能肯定会更好 - 这样您就知道您只是删除了事件。 IE。$(elements).unbind('click.my_app');。这显然意味着您必须使用绑定事件$(elements).bind('click.my_app', function(){...});

更具体地说:

自动调用匿名函数

(function(){
  /*
   running an anonymous function this way will never cause a memory
   leak because memory leaks (at least the ones we have control over) 
   require a variable reference getting caught in memory with the 
   JavaScript runtime still believing that the variable is in use, 
   when it isn't - meaning that it never gets garbage collected. 
   This construction has nothing to reference it, and so will be 
   forgotten the second it has been evaluated.
  */
})();

使用 jQuery 添加匿名事件监听器:

var really_large_variable = {/*Imagine lots of data here*/};

$(element).click(function(){
  /*
   Whilst I will admit not having investigated to see how jQuery
   handles its event listeners onunload, I doubt if it is auto-
   matically unbinding them. This is because for most code they
   wont cause a problem, especially if only a few are in use. For
   larger projects though it is a good idea to create some beforeunload
   or unload handlers that delete data and unbind any event handling.
   The reason for this is not to protect against the reference of the
   function itself, but to make sure the references the function keeps
   alive are removed. This is all down to how JS scope works, if you
   have never read up on JavaScript scope... I suggest you do so.

   As an example however, this anonymous function has access to the
   `really_large_variable` above - and will prevent any garbage collection
   system from deleting the data contained in `really_large_variable`
   even if this function or any other code never makes use of it. 
   When the page unloads you would hope that the browser would be able
   to know to clear the memory involved, but you can't be 100% certain
   it will *(especially the likes of IE6/7)* - so it is always best
   to either make sure you set the contents of `really_large_variable` to null
   or make sure you remove your references to your closures/event listeners.
  */
});

拆解与解构

关于我的解释,我重点关注何时不再需要该页面并且用户正在离开。然而,在当今的 ajax 内容和高度动态界面的世界中,上述内容变得更加重要; GUI 不断地创建和废弃元素。

如果您正在创建一个动态 JavaScript 应用程序,我无法强调构造函数的重要性.tearDown or .deconstruct当不再需要代码时执行的方法。这些应该逐步执行大型自定义对象构造并取消其内容,以及删除已动态创建且不再使用的事件侦听器和元素。你还应该使用 jQueryempty替换元素内容之前的方法 - 这可以用他们的话更好地解释:

http://api.jquery.com/empty/

为了避免内存泄漏,jQuery 在删除元素本身之前从子元素中删除其他构造,例如数据和事件处理程序。

如果您想删除元素而不破坏其数据或事件处理程序(以便稍后可以重新添加它们),请改用 .detach() 。

使用tearDown 方法进行编码不仅迫使您更加整洁(即确保将相关代码、事件和元素命名空间放在一起),这通常意味着您以更加模块化的方式构建代码;这对于您的应用程序的未来发展、可读性以及以后可能接管您的项目的任何其他人来说显然要好得多。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

避免内存泄漏/使用 Javascript 的相关文章

  • jQuery .push 到 .get 调用中的数组给出空结果

    谁能告诉我为什么下面给我一个空字符串 当我console log contentArray in the get 回调函数它显示数据 但是当我尝试在下面的代码中执行它时 结果为空 sectionArray contentArray func
  • 在版本 4.4.6 中禁用 ckeditor 上下文菜单

    我在 Rails4 项目中使用 ckeditor 我尝试了 ckeditor gem 和 ckeditor rails gem 来提供 ckeditor 库 这里有多个帖子 人们希望删除 ckeditor 上下文菜单 以便可以显示本机浏览器
  • 为什么 window 与 Internet Explorer 中的 window.self 不同?

    关于我如何遇到这个问题有一个复杂的背景故事 但为什么self属性不完全等于窗口本身 在 Safari 和 Firefox 及其朋友中 结果如我所料 gt window window self true gt window window se
  • 如何使用 Playwright 使用选择器查找框架 (iframe)

    我有一个小问题 无法找到使用 Microsoft Playwright 框架的答案 根据您可以使用以下代码获取 iframe const frame page frame frame login 但是如何使用选择器来查找 iframe 并与
  • Number.IsNaN() 比 isNaN() 更糟糕吗

    Soooooo isNaNJavaScript 显然被破坏了 比如 isNaN isNaN isNaN true isNaN false isNaN 0 返回 false 当它们看起来都是 不是数字 在 ECMAScript 6 中 草案包
  • 通过 JavaScript 获取表单名称

    我有一个简单的问题 但我在网上找不到好的解决方案 我有这个 HTML 代码
  • IntersectionObserver是否支持水平滚动观察?

    我制作了几个垂直滚动 IntersectionObserver 模块 但我对水平滚动感兴趣 根将是 div 观察目标将是 img 我想观察当 img 放大但 div 保持视口宽度时的变化 我什至不确定移动 Safari 是否会将缩放后的图片
  • JavaScript 验证和 PHP 验证?

    我正在使用 jquery 验证插件来验证空表单 我还应该在 PHP 中检查一下以确保 100 正确吗 或者用 javascript 验证就可以了 谢谢 您应该始终在服务器上进行验证 如果用户以某种方式不使用 Javascript 提交表单
  • React autoFocus 将光标设置为输入值的开头

    我有一个受控输入 最初显示一个值 我已将该输入设置为自动聚焦 但当我希望它出现在末尾时 光标出现在输入的开头 我知道这可能是因为自动对焦是在值之前添加的 但我不能 100 确定 在输入字段末尾完成光标初始化的最佳方法是什么 var Test
  • 如何使用角度材料在具有可扩展行的表格中创建嵌套垫表

    我有以下数据 id c9d5ab1a subdomain wing domain aircraft part id c9d5ab1a info mimetype application json info dependent parent
  • 计算三次贝塞尔曲线的弧长、曲线长度。为什么不工作?

    我正在用这个算法计算弧长 三次贝塞尔曲线的长度 function getArcLength path var STEPS 1000 gt precision var t 1 STEPS var aX 0 var aY 0 var bX 0
  • 如何使用 Javascript 设置查询字符串

    有没有办法使用 javascript 设置查询字符串的值 我的页面有一个过滤器列表 单击该列表时 它将更改右侧的页内结果窗格 我正在尝试更新 url 的查询字符串值 因此如果用户离开页面 然后单击 后退 按钮 他们将返回到最后一个过滤器选择
  • 使用 JavaScript 移动页面上的按钮

    我的按钮可以移动 但奇怪的是 我无法弄清楚偏移是否有问题 我希望我的按钮随着鼠标光标移动 但现在它的移动方式不是我想要的 有时它会消失 另外 创建的新按钮是重叠的 我不知道如何解决这个问题并拥有更好的外观 var coorA var coo
  • 编辑第一个选项名称

    我有以下我无法访问的代码 我想要做的是将一些文本添加到现在为空的第一个选项中 诸如 选择地址 之类的文本
  • Vaadin 12 将对象传递给 JavaScript 函数:无法对类进行编码

    Vaadin 12 Kotlin 项目 In my myPage html我有JavaScript myObject redirectToCheckout sessionId 1111 2222 所以我需要调用javaScript函数red
  • 聆听 Angular 2 中的元素可见性

    我正在为我的网络应用程序使用 Bootstrap 和 Angular 2 v4 我想监听指令中的元素以了解可见性变化 我的元素有一个可以隐藏其子元素的父元素hidden sm up我需要在每次隐藏或显示时触发一个函数 div hidden
  • 使用 Javascript 设置 cookie [重复]

    这个问题在这里已经有答案了 我正在尝试构建我的第一个移动应用程序 它需要连接到我的 mysql 数据库并使用 json 返回数据 这很好 目前我有一个登录系统 一旦确定用户名和密码存在 它就会返回一条成功消息 对于下一步 我想在我的页面上使
  • 如何使用 JavaScript 或 jQuery 克隆 HTML 元素的样式对象?

    我正在尝试克隆元素的样式对象 这应该允许我在更改后重置所述元素的样式 例如 el style left 50px curr style left 50px Modify the elements style The cloned style
  • react-native - 图像需要来自 JSON 的本地路径

    你好社区 我正在react native中开发一个测试应用程序 并尝试从本地存储位置获取图像 我实际在做什么 我将图像直接链接源提供给 var 并在渲染函数中调用此方法 react 0 14 8 react native 0 23 1 np
  • 如何通过索引访问 JSON 对象中的字段

    我知道这不是最好的方法 但我别无选择 我必须通过索引访问 JSONObject 中的项目 访问对象的标准方法是只写this objectName or this objectName 我还找到了一种获取 json 对象内所有字段的方法 fo

随机推荐

  • C# 中的匿名类型

    x is compiled as an int var x 10 y is compiled as a string var y Hello z is compiled as int var z new 0 1 2 but ano is c
  • Rails Mongoid 无法进行身份验证 - 失败并出现错误 13:“未授权对 my_db.my_collection 进行查询”

    这个问题据说最新版本的Moped已经解决了 但我仍然遇到这种情况 我有一个 Rails 4 2 应用程序Mongoid 为 MongoDB 数据库创建了一个用户读写 and dbOwner角色 并设置授权 真 in the mong con
  • MPAndroidChart LineChart:使用日期而不是字符串作为 X 轴

    MPAndroid图表折线图默认情况下接受 X 轴字符串 有没有办法将日期设置为 X 轴的数据类型 仅将日期转换为字符串的问题是图表可能会根据数据点而倾斜 例如 如果我在 1 月份有一个数据条目 在 6 月份有 10 个数据条目 则默认情况
  • Shiny - 在输出中使用观察函数调用的结果

    我有一个闪亮的应用程序 其中基于所选选项 列 数据集动态重新计算 重新计算的结果用于向用户显示另一组选项并创建绘图 目前我正在使用observe 读取用户选择 重新计算数据集并更新 UI 但是 当显示输出 图 时 我必须再次重新计算 因为o
  • 无法解析 com.android.support:appcompat-v7:28.0.0

    对此有很多不同的问题 但使用时存在问题v7 28 0 v7 28 v7 28 0 0 rc02但是当我同步我的项目时 我收到此错误 无法解决 app debug compileClasspath 的依赖关系 可以 无法解析 com andr
  • 如何防止 Android 设备从 Qt 应用程序进入睡眠状态

    我正在 Android 上部署 Qt 应用程序 需要防止设备进入待机状态 否则 我的线程会被中断 而且我的 BLE 连接也会丢失 我发现这样 如何以编程方式防止 Android 设备进入睡眠状态 应执行此 Java 代码 PowerMana
  • 如何知道每次通话/短信的 SimSlot 号码?

    您只知道广播接收器中的 sim 插槽号 经过一个月的研究 我得到了一个对我来说效果很好的解决方案 如下所示 首先将 android permission READ PHONE STATE 权限添加到您的清单文件中 实现电话事件接收器 为您的
  • 如何在 android 文本视图中使用 getlinecount()

    我想知道我的文本视图中有多少行 我已经设置了文本视图文本 然后我想获取文本视图中需要多少行 我使用 mytextview getLineCount 但它不起作用 它总是返回 0 有人能帮我吗 您需要发布获取行数的方法 这是示例代码 imag
  • C# Windows 服务自终止服务

    如何让服务自行终止 Environment Exit 将导致应用程序启动 但服务保持运行 任何想法 您可以使用 SCM 从服务本身关闭您的服务 System ServiceProcess ServiceController svc new
  • 启用 CORS 的服务器不拒绝请求

    我正在尝试使用快递Cors使用我的 resitfy 服务器 它似乎并没有拒绝来自其他 ip 的请求 我在本地工作 所以我尝试将 origin 设置为随机公共 IP 但我的所有请求仍在处理中 这是我的路线 module exports fun
  • Hibernate:删除多对多关联

    我有两个具有多对多关联的表 数据库片段 loads Id Name sessions Id Date 会话负载 LoadId会话ID Hibernate 映射片段 loads hbm xml
  • 跨数据库外键错误

    这是我的第一个数据库 DB1 的模型 from django db import models class Company models Model name models CharField max length 100 null Tru
  • 初始化 Objective-C 类别中的静态变量

    我试图创建一个静态变量来存储图像字典 不幸的是 我能找到的初始化它的最好方法是检查使用该变量的每个函数 由于我是在类别内创建此变量 因此我不能仅在初始化程序内初始化它 有没有更简洁的方法来初始化 navigationBarImages st
  • Typescript:对象和基元之间的 keyof typeof union 始终是 never

    首先 我的问题的一些背景信息 我有一个项目 在其中我通过 Socket IO 接收一个对象 因此我没有关于它的类型信息 此外 它是一种相当复杂的类型 因此需要进行大量检查以确保接收到的数据良好 问题是我需要访问由接收到的对象中的字符串指定的
  • 不(最大宽度:512px)不工作

    我有以下 HTML 页面 Foobar 但是 这对窗口没有响应width 媒体规则从未适用 如果我删除not 它按预期工作 我不明白什么not max width 是的 我知道还有其他方法可以完成同样的事情 并且not max width
  • 角度单元测试失败,但不是本地测试

    升级到 Angular 版本 11 后 Travis CI 上的单元测试现在失败 在本地 它们确实成功了 即使在使用相同的节点 nvm 和 npm 版本进行全新安装之后 所有单元测试的错误都是相同的 Failed fn bind is no
  • Java Regex 从 HTML 锚点 (...) 标记获取文本

    我正在尝试获取某个标签内的文本 所以如果我有 a href http something com Found a a 我希望能够检索Found text 我正在尝试使用正则表达式来做到这一点 我能够做到 如果 a href a a gt 我
  • 显示 w.r.t. 的语义转义字符

    考虑以下示例 gt ghci 外壳 gt writeFile d show d cat d d gt writeFile d d cat d d gt writeFile backslash show cat backslash gt wr
  • Python - 不支持的类型:范围和范围

    我在尝试运行脚本时遇到这个奇怪的错误 代码似乎是正确的 但似乎 python 3 不喜欢这部分 def function x if integer return int x else return x non nil randrange 2
  • 避免内存泄漏/使用 Javascript

    我是 jQuery 的新手 我有点困惑这是否正常或可能导致内存泄漏 代码如下 在某些日期过滤器上为每个新值调用此方法 function preapreTooltip chart var tickLength chart xAxis 0 ti