ES6 计算 属性 & 嵌套模板文字

ES6 Computed Property & nested template literal

请看下面的代码:

const config = {
  prefix: 'MYAPP',
  MYAPP_HOST: '1',
  MYAPP_HOST: '2',
  [ this.prefix + '_HOST' ]: 'localhost',
}

console.log(`${config.MYAPP_HOST}`)
console.log(`${config.${config.prefix}_HOST}`)

使两个输出都打印出来的正确方法是什么localhost

我知道一种制作方法

  [ this.prefix + '_HOST' ]: 'localhost',

工作是将this.prefix定义为一个函数,所以变成:

  [ this_prefix() + '_HOST' ]: 'localhost',

但是,我希望,因为 prefix 属于 const config,所以它可以在 const config 中定义,而不是 之外。

至于${config.prefix}_HOST,我只是想构造字符串MYAPP_HOST,但嵌套了模板文字。有什么办法让它成为可能吗?

编辑:

Nested template makes no sense

虽然我需要这样做的原因可能并不明显,因为问题已简化为关注技术,这里是 less我想要的简化版本。看看下面的代码:

const config = {
  prefix: 'MYAPP',
  app: { port: 3000 },
  db: { host: 'localhost', port: 27017, name: 'db' },

  url: function () { return `driver:/${process.env.MYAPP_HOST || this.db.host}:${process.env.MYAPP_PORT || this.db.port}/${process.env.MYAPP_NAME || this.db.name}` },
}

并且我不想在 process.env.MYAPP_... 中使用字符串文字 MYAPP,而是想使用 prefix 变量。不管是否有意义,这就是我需要做的。现在该怎么做?

更新:

以上问题的答案已经在很多地方流传,所以这里简单总结一下解决方案(给OP):

const prefix = 'MYAPP'
const config = {
  prefix,
  MYAPP_HOST: '1',
  MYAPP_HOST: '2',
  [ prefix + '_HOST' ]: 'localhost',
}
console.log(`${config.MYAPP_HOST}`)
console.log(`${config[config.prefix+'_HOST']}`)

谢谢大家,给大家点个赞!

const config = {
  prefix: 'MYAPP',
  MYAPP_HOST: '1',
  MYAPP_HOST: '2',
  [ this.prefix + '_HOST' ]: 'localhost',
}

以上在 config 声明时不起作用,this.prefixundefined。如果您登录 config,您会得到如下内容。注意 undefined_HOST.

{prefix: "MYAPP", MYAPP_HOST: "2", undefined_HOST: "localhost"}

如果你真的想这样做,请尝试跟随,

const config = {
  prefix: 'MYAPP'
}
config[config.prefix+'_HOST']='localhost'

没有嵌套模板文字这样的东西,因为它不需要。正如 中所解释的,这是通过括号表示法实现的,在模板文字和常规 JS 中都是如此。应该是:

url: function () {
  return `driver:/${process.env[this.prefix + '_HOST'] || this.db.host}:${process.env[this.prefix + '_PORT'] || this.db.port}/${process.env[this.prefix + '_NAME'] || this.db.name}`
}

通常甚至不需要这样做,因为这个模板文字非常混乱且难以阅读。模板文字的目的是提供 well-formatted 串接字符串,而这个违背了目的。

这样的表达式可以在适当样式的 third-party 代码中使用临时变量看到 - 是的,它可以在没有括号符号的情况下实现:

url: function () {
  const host = process.env[`${this.prefix}_HOST`] || this.db.host;
  ...
  return `driver:/${host}:${port}/${name}`;
}

漂亮、干净,不需要可能导致 linter 错误的非常长的行。

您的原始代码段不起作用,因为您不能 reference properties of the object literal during its definition(正如@Skyler 也解释的那样)。

但是,它在 url 方法 中应该工作得很好。我会写

const config = {
  prefix: 'MYAPP',
  app: { port: 3000 },
  db: { host: 'localhost', port: 27017, name: 'db' },
  prefixed_env(name) {
    return process.env[this.prefix+"_"+name];
    // or, with template literals:
    return process.env[`${this.prefix}_${name}`];
  },
  url() {
    const host = this.prefixed_env("HOST") || this.db.host,
          port = this.prefixed_env("PORT") || this.app.port,
          name = this.prefixed_env("NAME") || this.db.name;
    return `driver:/${host}:${port}/${name}`;
  },
};

而不是 this,您 can also refer 直接 config