How to set an object property value to its own variable name (during initialization if possible)?

huangapple go评论67阅读模式
英文:

How to set an object property value to its own variable name (during initialization if possible)?

问题

如何将对象属性值设置为其自身变量名(如果可能,在初始化期间)?

例如,在JavaScript中创建一个Enum(在class AA内):

class AA {
  static Color = {
    Red: 'Red', 
    Green: 'Green', 
    Blue: 'Blue', 
  }
}

我必须每次都重复字符串名称。

是否有更简单的方法来做到这一点,例如:

class AA {
  static Color = {
    Red: this.currentProperty.name, 
    Green: this.currentProperty.name, 
    Blue: this.currentProperty.name, 
  }
}

要求(不强制执行)和评论:

  • 请尽量保持这个尽可能简单(不要复杂/繁琐)。

  • (最难的要求。最好以初始化时显示的形式。我可能对此有点挑剔...(我知道这是非常主观的,这种东西甚至可能不存在)。

  • 变量值和变量名可以同时进行重构 - 无需分别更改它们。

  • 它不必是一个Enum(这个主题不仅限于Enum)。

  • 尝试使用Es6+

  • 尝试让Jsdoc能够将其识别为Enum(也许使用@emun (?<)),(主要用于自动完成/ Vscode上的类型提示)

  • 尝试让调试器能够将其识别为Enum并能够将值视为有意义的字符串

  • 我知道GitHub上有一些Enum库,例如

  • 我知道在Enum上使用Symbol()是必要的

  • 我知道需要使Enum不可变(私有+getter / Object.freeze

  • 我认为Object.keys()不能帮助(太繁琐?)

英文:

question

How to set an object property value to its own variable name (during initialization if possible)?

eg

For example, to create a Enum (inside class AA) in Javascript:

class AA {
  static Color = {
    Red: &#39;Red&#39;, 
    Green: &#39;Green&#39;, 
    Blue: &#39;Blue&#39;, 
  }
}

I have to repeat the String name everytime.

Is there a simpler way to do this, something like eg:

class AA {
  static Color = {
    Red: this.currentProperty.name, 
    Green: this.currentProperty.name, 
    Blue: this.currentProperty.name, 
  }
}

requirements (not mandatory) & comments

  • Please make this As Simple As Possible (dont be complicated/cumbersome).

    • (The hardest requirement. It would be best in the form shown above (during initialization).
    • I may be a bit picky on this... (I know this is very subjective, and such thing may not even exist)
    • though, any other thoughts are still welcome)
  • The variable value & variable name can be refactored at the same time -- without the need to change them separately.

  • It doesnt have to be an Enum (-- this topic is not limited to Enum only, a normal object will do)

  • Try to use Es6+

  • Try to let Jsdoc able to recognize this as an Enum (maybe the use of @emun (?<)), (mainly for autocompletion / Type hint on Vscode)

  • Try to let Debugger able to recognize this as an Enum & able to view the value as a meaningful string

  • Im aware of there are some Enum lib in github eg, not sure they are good enough / fit my style.

  • Im aware of the use of Symbol() on Enum

  • Im aware of need to make Enum immutable (private + getter / Object.freeze)

  • I dont think Object.keys() can help. (too cumbersome?)

答案1

得分: 2

以下是代码的中文翻译部分:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->
class AA {
  static Color = Object.fromEntries(['Red','Green','Blue'].map(i=>[i,i]))
}
console.log(AA.Color)

<!-- end snippet -->

或者,使用一个辅助方法:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->
function makeEnum(...props) { return Object.fromEntries(props.map(i=>[i,i])) }

class AA {
   static Color = makeEnum('Red','Green','Blue')
}

console.log(AA.Color)

<!-- end snippet -->

这可能有助于自动补全:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->
function makeEnum(obj) { return Object.fromEntries(Object.keys(obj).map(i=>[i,i])) }

class AA {
   static Color = makeEnum({Red:'', Green:'', Blue:''})
}

console.log(AA.Color)

<!-- end snippet -->

或者使用代理:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->
function makeEnum() {
  let o = {}, p = new Proxy(o, {get:(_,i)=>(i==='enum'?o:(o[i]=i,p))})
  return p
}

class AA {
  static Color = makeEnum().Red.Green.Blue.enum
}

console.log(AA.Color)

<!-- end snippet -->

包括Object.freeze()以防止重新赋值:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->
function makeEnum() {
  let o = {}, p = new Proxy(o, {get:(_,i)=>
    (i==='enum'?(Object.freeze(o),o):(o[i]=i,p))})
  return p
}

class AA {
  static Color = makeEnum().Red.Green.Blue.enum
}

console.log(AA.Color)
AA.Color.Red = 'Yellow'
console.log(AA.Color)

<!-- end snippet -->

另一个代理变体:使用new关键字触发对象冻结:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->
function Enum() {
  let o={}, p = new Proxy(function() {}, {
    construct: () => (Object.freeze(o),o),
    get:(_,i)=>(o[i]=i,p)
  });
  return p;
}

class AA {
  static Color = new (Enum().Red.Green.Blue)
}

console.log(AA.Color)
console.log(AA.Color.Red)
AA.Color.Red = 'Yellow' // 冻结的对象无法更改
console.log(AA.Color.Red)
AA.Color.Orange = 'Orange' // 冻结的对象无法接受新属性
console.log(AA.Color)

<!-- end snippet -->
英文:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

class AA {
  static Color = Object.fromEntries([&#39;Red&#39;,&#39;Green&#39;,&#39;Blue&#39;].map(i=&gt;[i,i]))
}
console.log(AA.Color)

<!-- end snippet -->

or, with a helper method:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function makeEnum(...props) { return Object.fromEntries(props.map(i=&gt;[i,i])) }

class AA {
   static Color = makeEnum(&#39;Red&#39;,&#39;Green&#39;,&#39;Blue&#39;)
}

console.log(AA.Color)

<!-- end snippet -->

this might help with autocompletion:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function makeEnum(obj) { return Object.fromEntries(Object.keys(obj).map(i=&gt;[i,i])) }

class AA {
   static Color = makeEnum({Red:&#39;&#39;, Green:&#39;&#39;, Blue:&#39;&#39;})
}

console.log(AA.Color)

<!-- end snippet -->

or using a proxy:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function makeEnum() {
  let o = {}, p = new Proxy(o, {get:(_,i)=&gt;(i===&#39;enum&#39;?o:(o[i]=i,p))})
  return p
}

class AA {
  static Color = makeEnum().Red.Green.Blue.enum
}

console.log(AA.Color)

<!-- end snippet -->

including Object.freeze() to prevent reassignment:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function makeEnum() {
  let o = {}, p = new Proxy(o, {get:(_,i)=&gt;
    (i===&#39;enum&#39;?(Object.freeze(o),o):(o[i]=i,p))})
  return p
}

class AA {
  static Color = makeEnum().Red.Green.Blue.enum
}

console.log(AA.Color)
AA.Color.Red = &#39;Yellow&#39;
console.log(AA.Color)

<!-- end snippet -->

another proxy variant: the new keyword is used to trigger freezing of the object:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function Enum() {
  let o={}, p = new Proxy(function() {}, {
    construct: () =&gt; (Object.freeze(o),o),
    get:(_,i)=&gt;(o[i]=i,p)
  });
  return p;
}

class AA {
  static Color = new (Enum().Red.Green.Blue)
}

console.log(AA.Color)
console.log(AA.Color.Red)
AA.Color.Red = &#39;Yellow&#39; // frozen object can&#39;t be changed
console.log(AA.Color.Red)
AA.Color.Orange = &#39;Orange&#39; // frozen object can&#39;t accept new properties
console.log(AA.Color)

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月10日 05:00:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75404374.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定