Показать сообщение отдельно
  #14 (permalink)  
Старый 04.08.2018, 03:32
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Вам на самом деле не нужна такая функция для перечисления, поскольку 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);
Ответить с цитированием