【问题标题】:js memory organization - closures versus objects? [closed]Node.js 内存组织 - 闭包与对象? [关闭]
【发布时间】:2013-06-26 22:55:52
【问题描述】:

当我使用 JS 进行开发时,我经常面临使用内部函数(闭包)捕获变量和使用对象之间的选择。

内部函数:

var x = ...;
var f = function() {
    // use x here
}

对象:

obj.x = ...;
obj.f = function() {
    // use x here
}

内部函数方法“感觉”更自然,但我想知道 - 是否担心以一种或另一种方式执行它会影响性能,以及做这种事情最惯用的方式是什么?

【问题讨论】:

  • 所以xfobj 会在某个本地范围内吗?请声明。如果没有,这个问题将只是关于命名空间。另外,如何访问第二个变体中的x
  • 微优化几乎不值得担心。如果两种方法之间的唯一关注或区别是内存微管理,那么您应该使用您喜欢的任何方法。对我来说,使用闭包而不是在对象上放置属性通常有明确的理由。内存从来都不是我决定使用哪种方法的一个因素,因为在 JavaScript 中管理内存的方式并不像在其他语言中那样。
  • 如果你使用闭包,你会受到作用域的限制,所以你最终可能会在顶级作用域中得到许多闭包,并且所有函数都是该作用域的后代。使用对象方法,您可以更轻松地访问在其他范围中设置的值,这应该可以提高代码的模块化。当然,没有一种方法适合所有情况。在任何相当复杂的应用程序中,您很可能会同时使用这两种方法。

标签: javascript performance object closures


【解决方案1】:

在一个普通 PC 有 8GB RAM 的时代,闭包与对象属性的内存使用似乎无关紧要。无论如何,在不平凡的应用程序中,仅使用闭包或仅使用属性值是非常不可能的。

如果您有一个代码模块,则对仅由该模块的方法在内部使用的变量使用闭包是有意义的。对需要跨模块共享的值使用属性也很有意义,而无需使用 getter 和 setter(例如,您想使用obj.property 而不是obj.getProperty())。

此外,属性访问比使用函数检索值更有效,但 getter 和 setter 可以提供重要的功能(例如值验证和完整性检查),而不是简单地读取或分配值。

与往常一样,根据任何看起来合适的标准(速度、代码可维护性、稳健性、跨浏览器支持等)使用适合您应用程序的东西。

【讨论】:

  • 我几乎认为不会对大多数应用程序产生很大的性能影响。感谢您概述每个用例。听起来一般来说,对于一个更好或更坏没有共识,只是互补。
  • 这与可用的 RAM 无关,因为您不会像那样为您的标签获取所有内存。例如,在 Chrome 中,您有 1gb 的限制。它与 GC 压力有关,使用的内存越多,速度就越慢。你将不能做这样的服务器端应用程序或任何 javascript 丰富的(游戏、编辑器、视频内容,而不是论坛或 CRUD)应用程序。关于方法调用的说法也大错特错,因为您可以轻松地编写代码,为这种情况引入函数内联。
  • @Esailija — 关键是考虑到可用的 RAM 量,闭包和对象属性之间的内存使用差异对于大多数用途来说是无关紧要的。 “像这样”是什么意思?您是在谈论代码或编译器级别的函数内联吗?内联是否可以用作 getter 和 setter 访问所有共享数据(即模块内和模块间)的一般策略?
  • @RobG "like this" 意味着你看到人们有时通过将方法放在构造函数中来创建他们的类的方式。内联是指尽可能由现代引擎自动完成的内联优化。具体取决于引擎,这里有一些限制 V8 和 SpiderMonkey here, and here
  • 这就是我的意思jsfiddle.net/LG8rB
【解决方案2】:

事实上,你在第二种情况下分配了额外的对象,否则它们在我看来是一样的。

函数是 JS 中的第一类对象,很容易忘记任何时候你看到function(){} 分配一个相对较胖的新函数对象。你可以把它想象成看到new Function()被调用 如果这样可以让您更清楚地了解对象分配。

只有当你有一个“构造函数”在其中定义函数并返回一个指向这些函数的对象时,这才是有害的。 这些函数中的每一个都是在您从构造函数创建的对象之上创建的单独对象。功能 与对象及其数据本身相比,它很容易占用 10-100 倍的内存,这当然取决于数据和方法的数量。

如果您正在编写应用程序,很容易考虑是否需要担心它。如果你知道的话 您的应用程序根本不会创建很多对象,那么从更大的角度来看,内存的浪费并不是那么糟糕。如果你是 编写通用库等,请不要为您无法满足需求的应用程序开发人员做出这些假设 预测。

【讨论】:

    猜你喜欢
    • 2013-05-01
    • 1970-01-01
    • 2010-10-04
    • 2011-11-22
    • 2015-01-19
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多