繁体   English   中英

是否有等效于函数原型变量的 Class?

[英]Is there a Class equivalent to prototype variables on Functions?

如果我有以下代码:

function Thing() {}
Thing.prototype.cache = {};

var a = new Thing();
var b = new Thing();

a.cache === b.cache // true

我如何使用适当的 Classes重写它?

我知道公共 class 字段,但这些字段是在实例上定义的,而不是在 class 原型上定义的。

// For Example:
class Thing {
  cache = {}
}

var a = new Thing();
var b = new Thing();

a.cache === b.cache // false

没有 class 语法可以将非方法放在原型上,之后您必须将它们贴上,如下所示:

 class Thing {} Thing.prototype.cache = {} // Example usage // const thing1 = new Thing() const thing2 = new Thing() thing1.cache.x = 2 console.log(thing2.cache.x)

然而,将可变数据放在原型上被许多人视为神奇且难以遵循。 这是实现非常相似效果的另一种方法。

 // This can alternativly be a static, private variable on the class. const thingCache = {} class Thing { cache = thingCache } // Example usage // const thing1 = new Thing() const thing2 = new Thing() thing1.cache.x = 2 console.log(thing2.cache.x)

但是,我真正建议的是在 class 上将此属性设为 static 属性 - 这就是 static 属性的用途,在许多实例之间共享单个数据。

 class Thing { static cache = {} } // Example usage // Thing.cache.x = 2 console.log(Thing.cache.x) // In some rare scenarios where you only have the instance, // and not the original class, you can still retrieve the original class const thing1 = new Thing() const thing2 = new Thing() thing1.constructor.cache.x = 2 console.log(thing2.constructor.cache.x)

您实施的称为class field ,正如您在您的案例中注意到的那样,它相当于:

class Thing {
  constructor() {
    this.cache = {};
  }
}

除了像在 ES5 中那样将它附加到原型之外,您别无选择,因为您在 class 中声明的所有内容都是:

  • 一个 class 字段(附加到实例)
  • 一个方法(附在原型上)
  • 一个 static 字段(附加到类)

 class Thing { } Thing.prototype.cache = {}; const obj1 = new Thing; const obj2 = new Thing; console.log(obj1.cache === obj2.cache);

我在这里发布了一个类似的问题: Not able to update a class property in ES6

附带说明一下,由于您没有使用constructor ,因此class是不必要的,因此您可以这样写:

 const proto = { cache: {} }; const obj1 = Object.create(proto); const obj2 = Object.create(proto); console.log(obj1.cache === obj2.cache);

您想创建一个static class 字段

然后根据 class 名称定义 getter 和 setter。

当您希望一个字段在每个 class 中仅存在一次时,公共 static 字段非常有用,而不是在您创建的每个 class 实例上。 这对于缓存、固定配置或您不需要跨实例复制的任何其他数据很有用。

公共 static 字段使用 static 关键字声明。 在使用Object.defineProperty()评估 class 时,它们被添加到 class 构造函数中。 从 class 构造函数再次访问它们。

  • 没有初始化器的字段被初始化为未定义。
  • 公共 static 字段不会在子类上重新初始化,但可以通过原型链访问。
  • 初始化字段时, this指的是 class 构造函数。 您也可以通过名称引用它,并使用super获取超类构造函数(如果存在)。

 class Thing { static _cache = {}; get cache() { return Thing._cache; } set cache(newValue) { Thing._cache = newValue; } } var a = new Thing(); var b = new Thing(); b.cache.key = "value"; console.log(a.cache === b.cache); console.log(a.cache)

正如 Scotty Jamison 所说,class 语法仍然没有提供在原型本身上创建字段的方法,因此您必须使用[class].prototype.field来完成。 但是,如果您希望在 class 声明本身中这样做,您可以使用 static 块:

class Thing {
    static {
        this.prototype.boofar = {};
    }
}

static 块中的代码将在 class 初始化时运行, this与 class 本身绑定。 可以说,这比仅在 class 声明之后分配值更令人困惑,因为使用static可能建议使用 static 属性,而不是继承的属性。 尽管如此,class 不依赖外部代码还是不错的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM