箭头函数 vs Class 方法内存占用

Arrow function vs Class methods memory footprint

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

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 都用作其原型的对象上,如下所示:

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

但是当你这样做时:

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 they close over(这将引用创建它们时创建的实例),这对于回调很方便。

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