javascript - 箭头函数与类方法内存占用

标签 javascript typescript class-method arrow-functions

我正在阅读有关箭头函数的内容(在 typescript 上下文中)。我遇到了这条线。

arrow function is created per object of type Handler. Methods, on the other hand, are only created once and attached to Handler's prototype. They are shared between all objects of type Handler.

来源:https://www.typescriptlang.org/docs/handbook/functions.html

我无法理解。如果有人可以解释,请回答。

最佳答案

当你有这个时:

class Example {
    method() {
    }
}

const e1 = new Example();
const e2 = new Example();

您有 一个 method 函数的副本,而不是两个。它位于 e1e2 都用作其原型(prototype)的对象上,如下所示:

        +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
        |                                             |
        \   +−−−−−−−−−−−−+                            |
Example−−+−>| (function) |                            |
            +−−−−−−−−−−−−+           +−−−−−−−−−−−−−+  |
            | prototype  |−−−−−−+−+−>|  (object)   |  |
            +−−−−−−−−−−−−+     /  /  +−−−−−−−−−−−−−+  |
                               | |   | constructor |−−+  +−−−−−−−−−−−−−−−−+
                               | |   | method      |−−−−>|   (function)   |
                               | |   +−−−−−−−−−−−−−+     +−−−−−−−−−−−−−−−−+
                               | |                       | name: "method" |
            +−−−−−−−−−−−−−−−+  | |                       +−−−−−−−−−−−−−−−−+
e1−−−−−−−−−>|   (object)    |  | |
            +−−−−−−−−−−−−−−−+  | |
            | [[Prototype]] |−−+ |
            +−−−−−−−−−−−−−−−+    |
                                 |
            +−−−−−−−−−−−−−−−+    |
e2−−−−−−−−−>|   (object)    |    |
            +−−−−−−−−−−−−−−−+    |
            | [[Prototype]] |−−−−+
            +−−−−−−−−−−−−−−−+

But when you do this:

class Example {
    constructor() {
        this.method = () => { };
    }
}

const e1 = new Example();
const e2 = new Example();

或者这个:

class Example {
    method = () => { };
}

const e1 = new Example();
const e2 = new Example();

你有两份 method 函数,一份用于e1,一份用于e2,就像这样:

        +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
        |                                                                      |
        \   +−−−−−−−−−−−−+                                                     |
Example−−+−>| (function) |                                                     |
            +−−−−−−−−−−−−+                                    +−−−−−−−−−−−−−+  |
            | prototype  |−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−+−>|  (object)   |  |
            +−−−−−−−−−−−−+                              /  /  +−−−−−−−−−−−−−+  |
                                                        | |   | constructor |−−+
            +−−−−−−−−−−−−−−−+                           | |   +−−−−−−−−−−−−−+
e1−−−−−−−−−>|   (object)    |                           | |
            +−−−−−−−−−−−−−−−+                           | |
            | [[Prototype]] |−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |
            | method        |−−+                          |
            +−−−−−−−−−−−−−−−+  |     +−−−−−−−−−−−−−−−−+   |
                               +−−−−>|   (function)   |   |
                                     +−−−−−−−−−−−−−−−−+   |
            +−−−−−−−−−−−−−−−+        | name: "method" |   |
e2−−−−−−−−−>|   (object)    |        +−−−−−−−−−−−−−−−−+   |
            +−−−−−−−−−−−−−−−+                             |
            | [[Prototype]] |−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
            | method        |−−+
            +−−−−−−−−−−−−−−−+  |     +−−−−−−−−−−−−−−−−+
                               +−−−−>|   (function)   |
                                     +−−−−−−−−−−−−−−−−+
                                     | name: "method" |
                                     +−−−−−−−−−−−−−−−−+

任何体面的 JavaScript 引擎都会在这些函数实例之间共享代码,但是函数实例本身必须是不同的,因为它们关闭不同的上下文(调用它们的构造函数的上下文)重新创建)。 (函数对象本身不需要很大,特别是在一个彻底优化的引擎中。如果你看一下 internal slots a function must have [实际上;引擎可以优化,只要它们的行为符合规范描述],只有 [[Environment]] 因它们而异。)

每个实例创建的箭头函数的优点是你不必担心它们被调用的是什么this,因为它们会忽略它;相反,他们使用 this 他们关闭(这将引用创建它们时创建的实例),这对于回调很方便。

该方法的优点是它是共享的,并且(在高度动态的环境中)如果它在原型(prototype)上被替换为不同的实现,e1e2 将使用更新后的实现。 (这是一种罕见的边缘情况。)

关于javascript - 箭头函数与类方法内存占用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51464318/

相关文章:

javascript - 如何检测 Javascript/JQuery 对象是否有高度?

javascript - VueJ 中的过滤器

javascript - 如果值的长度达到最大长度,如何在 div 和 tirm/slice 中添加复选框的值

java - 与 Java 相比,Objective-C 中类级别方法的区别和好处是什么

ios - 通过另一个类中的类方法执行Restkit配置

ruby-on-rails - 如何为我的 Rails 模型创建自定义方法

javascript - 为什么 JSON.parse 会抛出跨域错误?

javascript - 记住 slider 位置和延迟加载 - bxslider

reactjs - 如何解决 TypeScript 错误 "Type ' Dayjs' 缺少类型 'Date' 的属性“当将 Day.js 与 Material-UI DatePicker 一起使用时?

Typescript 变量存在检查