•  阅读 2 分钟

通过代理设置常量

在这篇博客文章中,描述快速设置常量的小技巧(考虑枚举值,但不是包裹在命名空间里)。这是一个学习问题,而不是在你的代码中实际使用。

简单版

TypeScript 枚举

作为例子,考虑下面的 TypeScript 枚举(JavaScript 自身没有枚举):

enum MyEnum {
  foo,
  bar,
  baz,
}

assert.equal(MyEnum.foo, 0)
assert.equal(MyEnum.bar, 1)
assert.equal(MyEnum.baz, 2)

我通常优先使用字符串作为枚举值,因为它们更容易调试:

enum MyEnum {
  foo = 'foo',
  bar = 'bar',
  baz = 'baz',
}

assert.equal(MyEnum.foo, 'foo')
assert.equal(MyEnum.bar, 'bar')
assert.equal(MyEnum.baz, 'baz')

单纯的 JavaScript 解决方案

在 JavaScript 中你可以更少的代码做到相同的事:

const keyProxy = new Proxy(
  {},
  {
    get(_target, propKey, _receiver) {
      return propKey
    },
  }
)
const { foo, bar, baz } = keyProxy

assert.equal(foo, 'foo')
assert.equal(bar, 'bar')
assert.equal(baz, 'baz')

这是如何工作的?我们结合两个部分来了解这些。

首先,代理(proxy)是一个对象,无论你是用什么键读取属性,总是得到该键作为值:

assert.equal(keyProxy.hello, 'hello')
assert.equal(keyProxy.world, 'world')

再者,使用解构表达式获取属性值让我们同时获取属性键和变量名。意味着,下面两个解构是等价的。

const { foo, bar, baz } = keyProxy
const { foo: foo, bar: bar, baz: baz } = keyProxy

Symbol 作为常量的值

如果你使用 Symbol 作为常量的值,类型将更加安全。行 A 是唯一改变的一行。

const keyProxy = new Proxy(
  {},
  {
    get(_target, propKey, _receiver) {
      return Symbol(propKey) // (A)
    },
  }
)
const { foo, bar, baz } = keyProxy

assert.equal(typeof foo, 'symbol')
assert.equal(String(foo), 'Symbol(foo)')

扩展阅读

本文由 吳文俊 翻译,原文地址 Setting up constants via proxies

> cd ..