【问题标题】:Get object literal string with extra string embellishments around it获取对象文字字符串,周围有额外的字符串装饰
【发布时间】:2018-04-26 19:20:39
【问题描述】:

我目前在 Typescript 中有一个对象字面量。比如:

const MyNamesStrings = {
    a: {
        b: "hello",
        c: "bye"
    }
    d: {
        e: "qwerty"
    }
}

但我想在每次访问它们时将它们包装在一些字符串中。字符串是相同的,如果它在文字中,看起来会非常难看和重复。这将使我能够更轻松地维护字符串。

我想创建一个MyNames 类,它的作用类似于具有执行此功能的代理:

const ab = MyNames.a.b //"[${hello}]" where the extra characters surround the text.
const ac = MyNames.a.c //"[${bye}]"

这在 Javascript/Typescript 中可行吗?如果不是,我总是可以用更平凡的方式来做。

【问题讨论】:

标签: javascript typescript object


【解决方案1】:

如果您确实需要您描述的行为,您可以使用实际的Proxy,前提是您的 JavaScript 引擎支持 ECMAScript 2015 或更高版本。对于您的用例来说,这可能有点过分了;如果MyNamesStrings 是不可变的,则从MyNamesStringsMyNames 的一次性转换会更有效。但是让我们假设您确实需要代理。这是实现它的一种方法:

function makeStringWrappingProxy<T extends object>(t: T): T {
  return new Proxy(t, {
    get<K extends keyof T>(target: T, prop: K) {
      const val = target[prop];
      if (typeof val === 'string') {
        return '[${' + val + '}]';
      } else if (typeof val === 'object') {
        return makeStringWrappingProxy(val as T[K] & object);
      } else {
        return val;
      }
    }
  });
}

这个想法是返回一个代理,它拦截对对象的所有属性检索。如果您正在获取字符串属性,请改为返回包装的字符串。如果您正在获取对象属性,请改为返回该属性的代理(这允许您深入了解属性的属性并仍然看到它们被包装)。否则,只需返回该属性。

让我们看看它的实际效果:

const MyNames = makeStringWrappingProxy(MyNamesStrings);
const ab = MyNames.a.b //"[${hello}]" as expected
const ac = MyNames.a.c //"[${bye}]" as expected as well.

所以它起作用了!同样,这假设您实际上想要这样做。代理不是特别高效(每个属性访问都会启动函数调用)、向后兼容(ES5 不支持它)或直观(您可以修改一个属性,但是当您之后读取该属性时,它不是您设置的到)。由你决定。

希望有所帮助;祝你好运!

【讨论】:

    【解决方案2】:

    基本上你可以做一个自定义的getter函数,而不是访问MyNamesStrings.a.b你可以做MyNamesStrings.propGetter('a.b')

    var MyNamesStrings = {
      a: {
        b: "hello",
        c: "bye"
      },
      d: {
        e: "qwerty"
      },
      propGetter: function(loc, start = "[${", end = "}]") {
        var split = loc.split('.');
        var value = this;
        for (var i = 0; i < split.length; i++) {
          if (value) {
            value = value[split[i]];
          }else{
              //stop looping because the previous value doesn't exist.
              break;
          }
        }
        return value ? start + value + end : undefined;
      }
    }
    
    var result = MyNamesStrings.propGetter('a.b');
    var result2 = MyNamesStrings.propGetter('d.e');
    var result3 = MyNamesStrings.propGetter('f.g.h.i');
    
    console.log(result);
    console.log(result2);
    console.log(result3);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-20
      • 1970-01-01
      • 2021-03-12
      相关资源
      最近更新 更多