美文网首页
TypeScript class 的静态成员变量

TypeScript class 的静态成员变量

作者: _扫地僧_ | 来源:发表于2021-08-13 10:46 被阅读0次

    Static Members

    类可能有静态成员。 这些成员与类的特定实例无关。 它们可以通过类构造函数对象本身访问:

    class MyClass {
      static x = 0;
      static printX() {
        console.log(MyClass.x);
      }
    }
    console.log(MyClass.x);
    MyClass.printX();
    

    Special Static Names

    有一些特殊的名称,不能用于 TypeScript class 的静态成员变量定义。

    从 Function 原型中覆盖属性通常是不安全/不可能的。 因为类本身就是可以用 new 调用的函数,所以不能使用某些静态名称。 名称、长度和调用等函数属性不能定义为静态成员:

    class S {
      static name = "S!";
    Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'S'.
    }
    

    Generic Classes

    类,很像接口,可以是通用的。 当使用 new 实例化泛型类时,其类型参数的推断方式与函数调用中的推断方式相同:

    class Box<Type> {
      contents: Type;
      constructor(value: Type) {
        this.contents = value;
      }
    }
    
    const b = new Box("hello!");
         
    const b: Box<string>
    

    Type Parameters in Static Members

    下列代码会出现语法错误:

    class Box<Type> {
      static defaultValue: Type;
    Static members cannot reference class type parameters.
    }
    

    请记住,类型总是被完全擦除! 在运行时,只有一个 Box.defaultValue 属性槽。 这意味着设置 Box<string>.defaultValue (如果可能的话)也会改变 Box<number>.defaultValue - 不好。 泛型类的静态成员永远不能引用类的类型参数。

    this at Runtime in Classes

    重要的是要记住 TypeScript 不会改变 JavaScript 的运行时行为,而且 JavaScript 以具有一些特殊的运行时行为而闻名。

    JavaScript 对此的处理确实不同寻常:

    class MyClass {
      name = "MyClass";
      getName() {
        return this.name;
      }
    }
    const c = new MyClass();
    const obj = {
      name: "obj",
      getName: c.getName,
    };
    
    // Prints "obj", not "MyClass"
    console.log(obj.getName());
    

    长话短说,默认情况下,函数内 this 的值取决于函数的调用方式。 在这个例子中,因为函数是通过 obj 引用调用的,所以它的 this 值是 obj 而不是类实例。

    这很少是你想要发生的! TypeScript 提供了一些方法来减轻或防止这种错误。

    方法1 - 使用箭头函数

    如果您有一个经常以丢失 this 上下文的方式调用的函数,则使用箭头函数属性而不是方法定义是有意义的:

    class MyClass {
      name = "MyClass";
      getName = () => {
        return this.name;
      };
    }
    const c = new MyClass();
    const g = c.getName;
    // Prints "MyClass" instead of crashing
    console.log(g());
    

    这有一些权衡:

    • 即使对于未使用 TypeScript 检查的代码,此值也保证在运行时是正确的
    • 这将使用更多内存,因为每个类实例都有自己的以这种方式定义的每个函数的副本
    • 不能在派生类中使用 super.getName,因为原型链中没有条目可以从中获取基类方法

    相关文章

      网友评论

          本文标题:TypeScript class 的静态成员变量

          本文链接:https://www.haomeiwen.com/subject/ofwhultx.html