簡體   English   中英

打字稿,靜態方法繼承

[英]Typescript, static method inheritance

我正在使用打字稿,但類之間的靜態繼承有問題

任何人都可以向我解釋以下結果:

class Foo {
    protected static bar: string[] = [];

    public static addBar(bar: string) {
        this.bar.push(bar);
    }

    public static logBar() {
        console.log(this.bar);
    }
}

class Son extends Foo {
    protected static bar: string[] = [];
}

class Daughter extends Foo {}

Foo.addBar('Hello');
Son.addBar('World');
Daughter.addBar('Both ?');
Foo.logBar();
Son.logBar();
Daughter.logBar();

當前結果:

[ 'Hello', 'Both ?' ]
[ 'World' ]
[ 'Hello', 'Both ?' ]

但我想要 :

[ 'Hello' ]
[ 'World' ]
[ 'Both ?' ]

我有沒有重新聲明靜態bar屬性的解決方案?

謝謝 !

理解staticclass的關鍵是子類的構造函數繼承自超類的構造函數。 字面上地。 class只是在構造函數創建的實例之間設置繼承,構造函數本身也處於繼承結構中。

FooSonDaughter的原型。 這意味着Daughter.barFoo.bar ,它是一個繼承的屬性。 但是您為Son自己的bar屬性和自己的數組,因此在Son查找bar找到Son自己的bar ,而不是Foo上的bar 這是一個更簡單的例子:

 class Foo { } class Son extends Foo { } class Daughter extends Foo { } Foo.bar = new Map([["a", "ayy"]]); console.log(Foo.bar.get("a")); // "ayy" // `Son` inherits `bar` from `Foo`: console.log(Son.bar === Foo.bar); // true, same Map object console.log(Son.bar.get("a")); // "ayy" // So does `Daughter` -- for now console.log(Daughter.bar === Foo.bar); // true, same Map object console.log(Daughter.bar.get("a")); // "ayy" // Retroactively giving `Son` its own static `bar` Son.bar = new Map(); console.log(Son.bar === Foo.bar); // false, different Map objects console.log(Son.bar.get("a")); // undefined

這就是為什么當您查看Foo.barDaughter.bar時會看到["Hello", "Both ?"] Foo.bar :這是同一個bar ,指向同一個數組。 但是您只能在Son.bar上看到["World"] ,因為它是指向不同數組的不同bar

為了將它們分開,您可能希望為每個構造函數提供自己的bar ,盡管您可以按照Nitzan Tomer 的建議使用Map


關於事物組織方式的更多細節。 有點像這樣:

 const Foo = {}; Foo.bar = []; const Son = Object.create(Foo); Son.bar = []; // Overriding Foo's bar const Daughter = Object.create(Foo); Foo.bar.push("Hello"); Son.bar.push("World"); Daughter.bar.push("Both ?"); console.log(Foo.bar); console.log(Son.bar); console.log(Daughter.bar);

如果你剛接觸它,這是一件非常令人驚訝的事情,但是你的三個類在內存中看起來像這樣:

+−−>Function.prototype 
                          +−−−−−−−−−−−−−−−+  |
Foo−−−−−−−−−−−−−−−−−−+−+−>|   (function)  |  |       
                    / /   +−−−−−−−−−−−−−−−+  |       
                    | |   | [[Prototype]] |−−+       +−−−−−−−−−−−+
                    | |   | bar           |−−−−−−−−−>|  (array)  |
                    | |   | addBar, etc.  |          +−−−−−−−−−−−+
                    | |   +−−−−−−−−−−−−−−−+          | length: 2 |
                    | |                              | 0: Hello  |
                    | +−−−−−−−−−−−−−+                | 1: Both ? |
                    |               |                +−−−−−−−−−−−+
                    +−−−−−−−−−−−−+  |
                                 |  |
              +−−−−−−−−−−−−−−−+  |  |
              |   (function)  |  |  |    
              +−−−−−−−−−−−−−−−+  |  |    
Daughter−−−−−>| [[Prototype]] |−−+  |
              +−−−−−−−−−−−−−−−+     |
                                    |
              +−−−−−−−−−−−−−−−+     |
              |   (function)  |     |       
              +−−−−−−−−−−−−−−−+     |       
Son−−−−−−−−−−>| [[Prototype]] |−−−−−+    +−−−−−−−−−−−+
              | bar           |−−−−−−−−−>|  (array)  |
              +−−−−−−−−−−−−−−−+          +−−−−−−−−−−−+
                                         | length: 1 |
                                         | 0: World  |
                                         +−−−−−−−−−−−+

@TJCrowder 在此線程中的回答中找到了對 OP 代碼中行為的非常詳細的解釋。

為了避免重新定義靜態成員的需要,您可以采用以下方法:

class Foo {
    private static bar = new Map<string, string[]>();

    public static addBar(bar: string) {
        let list: string[];

        if (this.bar.has(this.name)) {
            list = this.bar.get(this.name);
        } else {
            list = [];
            this.bar.set(this.name, list);
        }

        list.push(bar);
    }

    public static logBar() {
        console.log(this.bar.get(this.name));
    }
}

class Son extends Foo {}

class Daughter extends Foo {}

Foo.addBar('Hello');
Son.addBar('World');
Daughter.addBar('Both ?');

操場上的代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM