Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 10.08.2023, 16:04
Интересующийся
Отправить личное сообщение для Ctemmm9999 Посмотреть профиль Найти все сообщения от Ctemmm9999
 
Регистрация: 12.12.2021
Сообщений: 13

Классы на прототипах!
Есть такая задача!(На литкод решал)
var ArrayWrapper = function(nums) {
this.nums = nums;
};

ArrayWrapper.prototype.valueOf = function() {
return this.nums.reduce((sum, num) => sum + num, 0);
}

ArrayWrapper.prototype.toString = function() {
return `[${this.nums.join(',')}]`;
}

const obj1 = new ArrayWrapper([1,2]);
const obj2 = new ArrayWrapper([3,4]);

console.log(obj1 + obj2); // 10
console.log(String(obj1)); // "[1,2]"
console.log(String(obj2)); // "[3,4]"


Вопрос такой! никак не пойму! Почему методы не вызываются, а только экземпляр класса, и он автоматически вызывает метод, будь то приведение к строке или сложение экземпляров!(как он понимает какой метод вызывать) Причём если в консоль просто вывести экземпляр, то он никаких действий, будь то приведение к строке или сложение не делает!

А вот такая запись мне более понятна что откуда!
console.log(obj1.valueOf() + obj2.valueOf()); // 10
console.log(String(obj1.toString())); // "[1,2]"
console.log(String(obj2.toString())); // "[3,4]"

Подскажите пжл!
Ответить с цитированием
  #2 (permalink)  
Старый 10.08.2023, 16:44
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,590

Это стандартные "зарезервированные" методы вызываемые при приведении типов: valueOf - к числу(точнее к примитиву), toString - к строке.

Они просто неявяно вызываются для любых не-числа\не-строки когда их пытаются использовать как строку\число.

Есть ещё toJSON - для JSON.stringify, Symbol.iterator для итератора и т.п.
__________________
29375, 35

Последний раз редактировалось Aetae, 10.08.2023 в 16:57.
Ответить с цитированием
  #3 (permalink)  
Старый 10.08.2023, 16:44
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,126

Ctemmm9999,
Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.
Ответить с цитированием
  #4 (permalink)  
Старый 10.08.2023, 16:45
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

Так в спецификации установлено.
Если операнд оператора + (-, *,/... в общем там, где должно быть число) является объектом, то автоматически вызывается метод valueOf этого объекта (если он есть), который должен вернуть число.
Тоже самое, когда нужно из объекта получить строку, автоматически вызывается метод toString, который должен вернуть строку
Ответить с цитированием
  #5 (permalink)  
Старый 10.08.2023, 16:59
Интересующийся
Отправить личное сообщение для Ctemmm9999 Посмотреть профиль Найти все сообщения от Ctemmm9999
 
Регистрация: 12.12.2021
Сообщений: 13

Аааа. Теперь всё стало на свои места! Всем большое спасибо!
Ответить с цитированием
  #6 (permalink)  
Старый 10.08.2023, 17:16
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

Ну там немного все сложнее.
Сначала ищется метод [Symbol.toPrimitive], и если он установлен, то вызывается с параметром, указывающем, что надо получить (число или строку), а если его нет, то в зависимости от ситуации если надо получить число, сначала ищется valueOf потом toString (если valueOf нет), а если надо получить строку, то сначала ищется toString, а если нет, то valueOf

Т.е можно было записать так
var ArrayWrapper = function(nums) {
this.nums = nums;
};

ArrayWrapper.prototype[Symbol.toPrimitive] = function (hint) {
	if (hint==='default' || hint==='number') {
		return this.nums.reduce((sum, num) => sum + num, 0);
	}
	return `[${this.nums.join(',')}]`;
}

const obj1 = new ArrayWrapper([1,2]);
const obj2 = new ArrayWrapper([3,4]);

console.log(obj1 + obj2); // 10
console.log(String(obj1)); // "[1,2]"
console.log(String(obj2)); // "[3,4]"

Последний раз редактировалось voraa, 10.08.2023 в 17:22.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
JavaScript Используя иерархию и наследования, создать классы окна, окна с заголовком Forever_smile Internet Explorer 2 24.03.2021 23:38
Классы в jQuery (добавление, изменение) miha511 jQuery 0 29.03.2018 21:31
скрыть классы по маске kot_k_k Общие вопросы Javascript 9 30.08.2017 15:35
js-фреймворк, связывающий css классы и dom элементы Danxil Оффтопик 12 30.03.2014 18:41
Мастер классы по js l-liava-l Оффтопик 5 24.12.2012 17:30