Классы на прототипах!
Есть такая задача!(На литкод решал)
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]" Подскажите пжл! |
Это стандартные "зарезервированные" методы вызываемые при приведении типов: valueOf - к числу(точнее к примитиву), toString - к строке.
Они просто неявяно вызываются для любых не-числа\не-строки когда их пытаются использовать как строку\число. Есть ещё toJSON - для JSON.stringify, Symbol.iterator для итератора и т.п. |
Ctemmm9999,
Пожалуйста, отформатируйте свой код! Для этого его можно заключить в специальные теги: js/css/html и т.п., например: [html run] ... минимальный код страницы с вашей проблемой [/html] О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting. |
Так в спецификации установлено.
Если операнд оператора + (-, *,/... в общем там, где должно быть число) является объектом, то автоматически вызывается метод valueOf этого объекта (если он есть), который должен вернуть число. Тоже самое, когда нужно из объекта получить строку, автоматически вызывается метод toString, который должен вернуть строку |
Аааа. Теперь всё стало на свои места! Всем большое спасибо!
|
Ну там немного все сложнее.
Сначала ищется метод [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]" |
Часовой пояс GMT +3, время: 11:46. |