英文:
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: 'Red',
Green: 'Green',
Blue: 'Blue',
}
}
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(['Red','Green','Blue'].map(i=>[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=>[i,i])) }
class AA {
static Color = makeEnum('Red','Green','Blue')
}
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=>[i,i])) }
class AA {
static Color = makeEnum({Red:'', Green:'', Blue:''})
}
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)=>(i==='enum'?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)=>
(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 -->
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: () => (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' // frozen object can't be changed
console.log(AA.Color.Red)
AA.Color.Orange = 'Orange' // frozen object can't accept new properties
console.log(AA.Color)
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论