Вам на самом деле не нужна такая функция для перечисления, поскольку JavaScript предоставляет необходимые возможности для перечисления.
{
const coins = { Penny: 1, Nickel: 5, Dime: 10, Quarter: 25 };
const dime = coins.Dime;
let sum = 0;
for(const value of Object.values(coins)) {
sum += value;
}
alert(sum);
}
Или даже так...
{
const coins = { Penny: 1, Nickel: 5, Dime: 10, Quarter: 25 };
let sum = Object.values(coins).reduce((sum, value) => sum + value);
alert(sum);
}
Сообщение от RuBrain
|
Как часто на практике вообще применяется подобное?
|
На практике скорей применяются, например, цикл for-in, функция Object.values, функция(-генератор) как значение свойства Symbol.iterator у объекта, описывающая, как перечислять объект.
Вот тот пример с игральными картами, но написанный с учётом возможностей JavaScript...
function Card(suit, rank) {
this.suit = suit;
this.rank = rank;
}
Card.Suits = { Clubs: 1, Diamonds: 2, Hearts: 3, Spades: 4 };
Card.Rank = {
Two: 2, Three: 3, Four: 4, Five: 5, Six: 6,
Seven: 7, Eight: 8, Nine: 9, Ten: 10,
Jack: 11, Queen: 12, King: 13, Ace: 14
};
function Deck() {
this.cards = [];
for(const suit of Object.values(Card.Suits))
for(const rank of Object.values(Card.Rank))
this.cards.push(new Card(suit, rank));
}
var deck = new Deck();
console.log(deck);
Можно сделать объект перечисляемым, добавив в него метод Symbol.iterator, в котором будет указано, каким образом перечислять, например я могу захотеть перечислять достоинства карт так, как они обозначаются на игральных картах...
var ranks = {
Two: 2, Three: 3, Four: 4, Five: 5, Six: 6,
Seven: 7, Eight: 8, Nine: 9, Ten: 10,
Jack: 11, Queen: 12, King: 13, Ace: 14,
* [Symbol.iterator]() {
for(const v in this) {
yield this[v] <= 10 ? this[v] : v[0];
}
}
};
// оператор расширения использует доступный итератор (он определён как Symbol.iterator)
console.log([...ranks]);
// Или можно использовать цикл for-of без Object.values,
// ranks стал перечислимым, поскольку содержит свойство-метод Symbol.iterator
for(const rank of ranks) {
console.log(rank);
}
Перечислимость объекта определяется наличием свойства-метода Symbol.iterator
Если вам всё-таки нужен тип данных, чьё множество значении представляет собой ограниченный список идентификаторов, то подойдут символьные примитивы.
Например, функцию enumeration (давайте я её назову Enum) можно определить так...
function Enum([definition]) {
return Object.freeze(
definition
.trim()
.split(/\s+/)
.reduce((m, p) => ({
...m,
[p]: Symbol(p),
__proto__: null
}), {})
);
}
// Примеры
const Color = Enum`
RED
GREEN
BLUE
`;
const Cardsuits = Enum`
CLUBS
DIAMONDS
HEARTS
SPADES
`;
console.log(Color, Cardsuits);
Хотя, такая функция в каком-то смысле лишняя, поскольку можно напрямую работать с символами...
const Color = Object.freeze({
RED: Symbol("RED"),
GREEN: Symbol("GREEN"),
BLUE: Symbol("BLUE")
});
console.log(Color);