gpt4 book ai didi

javascript - Lambda 函数与绑定(bind)、内存! (和性能)

转载 作者:行者123 更新时间:2023-12-03 02:09:56 27 4
gpt4 key购买 nike

我想确定等效解决方案之间哪个是最佳实践。用例是监听事件的类的实例。阿克塞尔·劳施梅尔博士prefers the lambda为了可读性。我同意他的观点。但就性能和内存消耗而言,哪个最好?

使用 lambda 函数

class Abc {
constructor() {
let el = document.getElementById("my-btn")
if (el)
el.addEventListener("click", evt => this.onClick(evt))
}
onClick(evt) {
console.log("Clicked!", evt.target)
}
}

有人可以确认或确认局部变量(此处为el)是否无法被垃圾收集器清除吗?或者,现代浏览器是否能够检测到它们在闭包中未被使用?

Function.prototype.bind :

class Abc {
constructor() {
let el = document.getElementById("my-btn")
if (el)
el.addEventListener("click", this.onClick.bind(this))
}
onClick(evt) {
console.log("Clicked!", evt.target)
}
}

不存在内存问题,但所有基准测试都表明 bind 比闭包慢得多(示例 here )。

编辑:我不同意忽略 bind 性能问题的评论。我建议阅读this answer以及Chrome中的实现代码。它不可能有效率。我坚持认为:我看到的所有基准测试在所有浏览器上都显示相似的结果。

有没有办法同时拥有低内存使用率和良好的性能?

最佳答案

闭包(或箭头函数,又名lambda)不会导致内存泄漏

Can someone to confirm or infirm if the local variables (here el) can't be cleared by the garbage collector? Or, are modern browsers capable to detect they are unused in the closure?

是的,现代 JavaScript 引擎能够检测父作用域中的变量,这些变量在闭包中可见但未使用。我找到了一种方法来证明这一点。

第 1 步:闭包使用 10 MB 的变量

我在 Chromium 中使用了这段代码:

class Abc {
constructor() {
let arr = new Uint8Array(1024*1024*10) // 10 MB
let el = document.getElementById("my-btn")
if (el)
el.addEventListener("click", ev => this.onClick(ev, arr))
}
onClick(ev) {
console.log("Clicked!", ev.target)
}
}

new Abc()

请注意 Uint8Array 类型的变量 arr。这是一个typed array大小为 10 兆字节。在第一个版本中,变量 arr 在闭包中使用。

然后,在 Chromium 开发者工具的“配置文件”选项卡中,我拍摄了堆快照:

Snapshot 1: the variable <code>arr</code> is used in the closure

按大小递减排序后,第一行是:“system/JSArrayBufferData”,大小为 10 MB。这是我们的变量arr

第 2 步:10 MB 的变量可见,但在闭包中未使用

现在我只需删除这行代码中的 arr 参数:

            el.addEventListener("click", ev => this.onClick(ev))

然后,第二个快照:

Snapshot 2: the variable <code>arr</code> is not used in the closure

第一行已经消失。

这一经验证实,垃圾收集器能够清除父作用域中可见但在事件闭包中未使用的变量。

关于Function.prototype.bind

我引用Google JavaScript Style Guide ,有关箭头函数的部分:

Never call f.bind(this) or goog.bind(f, this) (and avoid writing const self = this). All of these can be expressed more clearly and less error-prone with an arrow function. This is particularly useful for callbacks, which sometimes pass unexpected additional arguments.

Google 明确建议使用 lambda 而不是 Function.prototype.bind

相关:

<小时/>

关于javascript - Lambda 函数与绑定(bind)、内存! (和性能),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42117911/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com