Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 02.08.2018, 12:05
Интересующийся
Отправить личное сообщение для RuBrain Посмотреть профиль Найти все сообщения от RuBrain
 
Регистрация: 20.04.2018
Сообщений: 21

Сообщение от рони Посмотреть сообщение
/Array/forEach
ОК, если массив, то все понятно, но каким образом Card.Suit становится массивом? В дебагере если я останавливаюсь на нем, то это объект-функция с некоторыми значениями. В Card.Suit свой метод foreach, который принимает 2 аргумента f и c. С первым f вроде понятно, туда передается функция cards.push(new Card(suit, rank), а что с "c"?
Ответить с цитированием
  #12 (permalink)  
Старый 02.08.2018, 13:51
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Сообщение от RuBrain
но каким образом Card.Suit становится массивом?
никаким, но в Card.Suit есть массив и есть метод обработки каждого элемента массива enumeration.foreach
значит s это f.call(c,this.values[i]); или currentValueТекущий обрабатываемый элемент в массиве.

enumeration.foreach не нативный, но он делает тоже самое что forEach в Array.
Ответить с цитированием
  #13 (permalink)  
Старый 02.08.2018, 14:15
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

RuBrain,
Что-то у вас отличается, второй вариант не имеет смысла, оно итак так.
var proto = enumeration.prototype = {
    constructor: enumeration,                   // Identify type
    toString: function() { return this.name; }, // Return name
    valueOf: function() { return this.value; }, // Return value
    toJSON: function() { return this.name; }    // For serialization
};

var proto = enumeration.prototype = {
    constructor: enumeration,                   // Identify type
};

И что-то сам автор начудил с этой функцией enumeration, как-то это он не по javascript-ному сделал, зачем-то всё засунул в свойства функции и запретил ее вызывать, наверное по опыту из какого-то другого языка, где всякие статические классы есть, он это сделал, но без лишних понтов смысл такой:
function Enumeration(namesToValues) {
    this.values = [];
    for (var name in namesToValues) {
        var enumerable = new Enumerable(name, namesToValues[name]);
        this[name] = enumerable;
        this.values.push(enumerable);
    }
}
Enumeration.prototype.foreach = function(callback, context) {
    for (var i = 0; i < this.values.length; i++) callback.call(context, this.values[i]);
};
Enumeration.prototype.print = function() {
    console.log(this.values);
};

function Enumerable(name, value) {
    this.name = name;
    this.value = value;
}
Enumerable.prototype.toString = function() { return this.name; }; 
Enumerable.prototype.valueOf = function() { return this.value; };
Enumerable.prototype.toJSON = function() { return this.name; };

console.log('Suit', new Enumeration({Clubs: 1, Diamonds: 2, Hearts:3, Spades:4}));

Последний раз редактировалось Rise, 02.08.2018 в 15:03.
Ответить с цитированием
  #14 (permalink)  
Старый 03.08.2018, 13:10
Интересующийся
Отправить личное сообщение для RuBrain Посмотреть профиль Найти все сообщения от RuBrain
 
Регистрация: 20.04.2018
Сообщений: 21

Сообщение от Rise Посмотреть сообщение
RuBrain,
Что-то у вас отличается, второй вариант не имеет смысла, оно итак так.
Я удалил не нужное, чтобы проще читался код.


Сообщение от Rise Посмотреть сообщение
И что-то сам автор начудил с этой функцией enumeration, как-то это он не по javascript-ному сделал, зачем-то всё засунул в свойства функции и запретил ее вызывать, наверное по опыту из какого-то другого языка, где всякие статические классы есть, он это сделал, но без лишних понтов смысл такой:
Ну он вот как объяснил:

Пример 9.7 содержит единственную функцию enumeration(). Однако она не является конструктором: она не определяет класс с именем «enumeration». Но она является фабричной функцией: при каждом вызове она создает и возвращает новый класс. Ниже показано, как ее можно использовать:

var Coin = enumeration({Penny: 1, Nickel:5, Dime:10, Quarter:25});
var c = Coin.Dime; // This is an instance of the new class
c instanceof Coin // => true: instanceof works
c.constructor == Coin // => true: constructor property works
Coin.Quarter + 3*Coin.Nickel // => 40: values convert to numbers
Coin.Dime == 10 // => true: more conversion to numbers
Coin.Dime > Coin.Nickel // => true: relational operators work
String(Coin.Dime) + ":" + Coin.Dime // => "Dime:10": coerce to string
Ответить с цитированием
  #15 (permalink)  
Старый 03.08.2018, 13:17
Интересующийся
Отправить личное сообщение для RuBrain Посмотреть профиль Найти все сообщения от RuBrain
 
Регистрация: 20.04.2018
Сообщений: 21

Сообщение от рони Посмотреть сообщение
никаким, но в Card.Suit есть массив и есть метод обработки каждого элемента массива enumeration.foreach
значит s это f.call(c,this.values[i]); или currentValueТекущий обрабатываемый элемент в массиве.

enumeration.foreach не нативный, но он делает тоже самое что forEach в Array.
Да, там есть массив Card.Suit.values, с ним вроде как все ясно. Не совсем понятна переменная c.
Ответить с цитированием
  #16 (permalink)  
Старый 03.08.2018, 13:37
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Сообщение от RuBrain
Не совсем понятна переменная c
нет c, нет контекста в данном случае.
Ответить с цитированием
  #17 (permalink)  
Старый 03.08.2018, 16:52
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Сообщение от RuBrain
Но она является фабричной функцией: при каждом вызове она создает и возвращает новый класс. Ниже показано, как ее можно использовать:
Мой пример тоже можно использовать, ну кроме "c instanceof Coin" и "c.constructor == Coin". Недостаток у автора в том, что он плодит одинаковые функции foreach, toString, valueOf, toJSON в памяти, например, 100 вызовов enumeration даст по 100 их копий, таких методов может быть много, вон вы например print придумали, и все они будут так размножаться. У него получилась какая-то пародия на паттерн Singleton/Multiton и Static class, непонятно зачем так извращаться.

Последний раз редактировалось Rise, 03.08.2018 в 17:08.
Ответить с цитированием
  #18 (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);
Ответить с цитированием
  #19 (permalink)  
Старый 04.08.2018, 09:39
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Malleys,
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
стрелки вниз, верх при раздвижение блоков dima018 Элементы интерфейса 8 12.02.2018 21:29
Запустить пример с главной страницы Shasoft Angular.js 2 12.01.2014 20:55
Помогите повторить пример (Яндекс-карт) hrundel Общие вопросы Javascript 0 19.09.2013 18:45
nodeJS нужен пример кода для логина в сайт unet900 AJAX и COMET 0 02.07.2013 19:59
Пример из учебника на сайте jekahm Общие вопросы Javascript 4 04.10.2012 13:33