如何优雅的使用枚举功能——Constants

背景

在项目中,或多或少的会遇到使用枚举/快码/映射/字典,它们一般长这个样子。(PS:我不知道怎么称呼这个玩意)

在一些需要展示的地方,会使用下面的代码来展示定义。

<div>{{ statusList[status] }}</div>
复制代码

而在代码中,又会使用下面的形式进行判断。这样写会让代码里充斥着许多的 'draft' 字符串,非常不利于管理。

if (status === 'draft') {
    // do sth...
}
复制代码

基于这种情况,在使用时会先声明一个变量。

const DRAFT = 'draft'

if (status === DRAFT) {
    // do sth...
}
复制代码

为了应对整个项目都会使用到的情况,会这样处理。

export const statusList = {
  draft: '草稿',
  pending: '待处理',
}

export const statusKeys = {
  draft: 'draft',
  pending: 'pending',
}
复制代码

看了隔壁后端同事的代码,在 Java 里,枚举的定义及使用一般是如下形式。于是我就有了写这个工具类的想法。

public enum Status {
	DRAFT('draft', '草稿');
    
    Status(String code, String name) {
    	this.code = code;
        this.name = name;
    }
    
    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }
}

public void aFunction() {
    const draftCode = Status.DRAFT.getCode();
}
复制代码

Constants

直接上代码

const noop = () => {}

class Constants {
  constructor(obj) {
    Object.keys(obj).forEach((key) => {
      const initValue = obj[key];
      if (initValue instanceof Object) {
        console.error(`Warnning: this util only support primitive values, current value is ${JSON.stringify(initValue)}`)
        // throw new Error(`Warnning: this util only support primitive values, current value is ${JSON.stringify(initValue)}`)
      }
      const newKey = `_${key}`;
      this[newKey] = initValue;
      Object.defineProperty(this, key, {
        configurable : true,
        enumerable : true,
        get: function() {
          const value = this[newKey];
          const constructorOfValue = value.constructor;
          const entry = [key, value];
          ['getKey', 'getValue'].forEach((item, index) => {
            constructorOfValue.prototype[item] = () => {
              constructorOfValue.prototype.getKey = noop;
              constructorOfValue.prototype.getValue = noop;
              return entry[index];
            }
          })
          return value;
        },
        set: function(newValue) {
          this[newKey] = newValue;
        }
      })
    });
  }
}
复制代码

测试

const testValues = {
  draft: '草稿',
  id: 1,
  money: 1.2,
  isTest: true,
  testObj: {},
  testArray: [],
}
const constants = new Constants(testValues)

const test = (result, expect) => {
  const isExpected = result === expect
  if (isExpected) {
    console.log(`PASS: The result is ${result}`)
  } else {
    console.error(`FAIL: the result is ${result}, should be ${expect}`)
  }
}

test(constants.draft, '草稿')
test(constants.draft.getKey(), 'draft')
test(constants.draft.getValue(), '草稿')

test(constants.id, 1)
test(constants.id.getKey(), 'id')
test(constants.id.getValue(), 1)

test(constants.money, 1.2)
test(constants.money.getKey(), 'money')
test(constants.money.getValue(), 1.2)

test(constants.isTest, true)
test(constants.isTest.getKey(), 'isTest')
test(constants.isTest.getValue(), true)
a = 'test'
test(a.getKey(), undefined)
test(a.getValue(), undefined)
复制代码

猜你喜欢

转载自juejin.im/post/7033220309386395679