toString
Каждый объект обладает методом toString , который вызывается автоматически каждый раз, когда требуется строковое представление объекта.
Например, это произойдет в вызовах:
// alert требует строку, // поэтому произойдет неявный вызов obj.toString alert(obj) // операция объединения строк сделает строку из obj var s = 'Объект в виде строки:'+obj
Объект Object предоставляет базовый метод toString , который обычно перекрывается наследующими от Object объектами.
По умолчанию, если этот метод не перекрыт объектом-наследником Object — он возвращает «[object ]».
var o = new Object(); alert(o.toString()) // [object Object]
Каждый основной объект яваскрипт обладает своим собственным методом toString , например:
var d = new Date() alert(d) // выведет d.toString()
Полезной практикой является перекрытие toString для новых типов объектов. Метод toString не получает аргументов и возвращает строку. Как правило, эта строка содержит основную информацию об объекте.
function Dog(name,color) < this.name=name this.color=color >theDog = new Dog("Барбос","черный");
Если вызвать метод toString сейчас, то он вернет [object Object] .
Для изменения этого поведения добавим в прототип свой метод toString :
Dog.prototype.toString = function() < return "Собака " + this.name + ", цвет:" + this.color >theDog = new Dog("Барбос","черный"); alert(theDog) // => "Собака Барбос, цвет: черный"
Каждый раз, когда объект theDog будет использован в качестве строки, яваскрипт автоматически вызовет метод toString , который вернет «Собака Барбос, цвет: черный».
Также стоит упомянуть, что эта функция позволяет пребразовать число к различным системам счисления:
number.toString( [radix] ),
где radix — целое число от 2 до 36, обозначающее систему счисления для чисел
var a = 9; a.toString(16); // '9' var b = 10; b.toString(16); // 'a' var с = 2; с.toString(2); // '10'
В последнем коде ошибка.
Строка 2:
var a = 9; a.toString(16); // '9' // Должно быть a.toString(10);
Ошибок нет, т.к. число 9 будет записываться так в любой системе счисления с основанием 10 и выше.
var a = 9; a.toString(2); // '1001' a.toString(6); // '13' a.toString(9); // '10' a.toString(10); // '9' a.toString(16); // '9' a.toString(20); // '9'
Отправить комментарий
- Полезные.
- Дополняющие прочитанное.
- Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
Для остальных вопросов и обсуждений есть форум.
Учебник javascript
Основные элементы языка
Сундучок с инструментами
Интерфейсы
Все об AJAX
Оптимизация
Разное
- Асинхронное программирование
- Google Gears в деталях
- Javascript Flash мост
- Букмарклеты и правила их написания
- О подборке книг на сайте
- Почему — плохо
- Способы идентификации в интернете
- Уровни DOM
- Что почитать?
- Шаблонизация с javascript
- Юнит-тесты уровня браузера на связке Selenium + PHP.
- Справочники: Javascript/HTML/CSS
- Система сборки и зависимостей Google Closure Library
- Хранение данных на клиенте. DOM Storage и его аналоги.
- 10 лучших функций на JavaScript
- https://wonkachocolatebars.com
7 часов 19 минут назад - packman disposables
7 часов 21 минута назад - packman disposables
7 часов 21 минута назад - Adderall XR
7 часов 22 минуты назад - Adderall XR
7 часов 23 минуты назад - Adderall XR
7 часов 24 минуты назад - This is really very nice blog and so.
12 часов 14 минут назад - Good to know about this! Tilers.
12 часов 14 минут назад - Thats what I was looking for! air.
12 часов 14 минут назад - Such a great post! Glenelg North
12 часов 15 минут назад
Преобразование объектов: toString и valueOf
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/object-toprimitive.
Ранее, в главе Преобразование типов для примитивов мы рассматривали преобразование типов для примитивов. Теперь добавим в нашу картину мира объекты.
Бывают операции, при которых объект должен быть преобразован в примитив.
- Строковое преобразование – если объект выводится через alert(obj) .
- Численное преобразование – при арифметических операциях, сравнении с примитивом.
- Логическое преобразование – при if(obj) и других логических операциях.
Рассмотрим эти преобразования по очереди.
Логическое преобразование
Проще всего – с логическим преобразованием.
Любой объект в логическом контексте – true , даже если это пустой массив [] или объект <> .
Строковое преобразование
Строковое преобразование проще всего увидеть, если вывести объект при помощи alert :
var user = < firstName: 'Василий' >; alert( user ); // [object Object]
Как видно, содержимое объекта не вывелось. Это потому, что стандартным строковым представлением пользовательского объекта является строка «[object Object]» .
Такой вывод объекта не содержит интересной информации. Поэтому имеет смысл его поменять на что-то более полезное.
Если в объекте присутствует метод toString , который возвращает примитив, то он используется для преобразования.
var user = < firstName: 'Василий', toString: function() < return 'Пользователь ' + this.firstName; >>; alert( user ); // Пользователь Василий
Метод toString не обязан возвращать именно строку.
Его результат может быть любого примитивного типа. Например, это может быть число, как в примере ниже:
var obj = < toString: function() < return 123; >>; alert( obj ); // 123
Поэтому мы и называем его здесь «строковое преобразование», а не «преобразование к строке».
Все объекты, включая встроенные, имеют свои реализации метода toString , например:
alert( [1, 2] ); // toString для массивов выводит список элементов "1,2" alert( new Date ); // toString для дат выводит дату в виде строки alert( function() <> ); // toString для функции выводит её код
Численное преобразование
Для численного преобразования объекта используется метод valueOf , а если его нет – то toString :
var room = < number: 777, valueOf: function() < return this.number; >, toString: function() < return this.number; >>; alert( +room ); // 777, вызвался valueOf delete room.valueOf; // valueOf удалён alert( +room ); // 777, вызвался toString
Метод valueOf обязан возвращать примитивное значение, иначе его результат будет проигнорирован. При этом – не обязательно числовое.
У большинства встроенных объектов такого valueOf нет, поэтому численное и строковое преобразования для них работают одинаково.
Исключением является объект Date , который поддерживает оба типа преобразований:
alert( new Date() ); // toString: Дата в виде читаемой строки alert( +new Date() ); // valueOf: кол-во миллисекунд, прошедших с 01.01.1970
Если посмотреть в стандарт, то в пункте 15.2.4.4 говорится о том, что valueOf есть у любых объектов. Но он ничего не делает, просто возвращает сам объект (непримитивное значение!), а потому игнорируется.
Две стадии преобразования
Итак, объект преобразован в примитив при помощи toString или valueOf .
Но на этом преобразования не обязательно заканчиваются. Вполне возможно, что в процессе вычислений этот примитив будет преобразован во что-то другое.
Например, рассмотрим применение к объекту операции == :
var obj = < valueOf: function() < return 1; >>; alert( obj == true ); // true
Объект obj был сначала преобразован в примитив, используя численное преобразование, получилось 1 == true .
Далее, так как значения всё ещё разных типов, применяются правила преобразования примитивов, результат: true .
То же самое – при сложении с объектом при помощи + :
var obj = < valueOf: function() < return 1; >>; alert( obj + "test" ); // 1test
Или вот, для разности объектов:
var a = < valueOf: function() < return "1"; >>; var b = < valueOf: function() < return "2"; >>; alert( a + b ); // "12" alert( a - b ); // "1" - "2" = -1
Объект Date по историческим причинам является исключением.
Бинарный оператор плюс + обычно использует численное преобразование и метод valueOf . Как мы уже знаем, если подходящего valueOf нет (а его нет у большинства объектов), то используется toString , так что в итоге преобразование происходит к строке. Но если есть valueOf , то используется valueOf . Выше в примере как раз a + b это демонстрируют.
У объектов Date есть и valueOf – возвращает количество миллисекунд, и toString – возвращает строку с датой.
…Но оператор + для Date использует именно toString (хотя должен бы valueOf ).
// бинарный плюс для даты toString, для остальных объектов valueOf alert( new Date + "" ); // "строка даты"
Других подобных исключений нет.
В языке Java (это не JavaScript, другой язык, здесь приведён для примера) логические значения можно создавать, используя синтаксис new Boolean(true/false) , например new Boolean(true) .
В JavaScript тоже есть подобная возможность, которая возвращает «объектную обёртку» для логического значения.
Эта возможность давно существует лишь для совместимости, она и не используется на практике, поскольку приводит к странным результатам. Некоторые из них могут сильно удивить человека, не привыкшего к JavaScript, например:
var value = new Boolean(false); if (value) < alert( true ); // сработает! >
Почему запустился alert ? Ведь в if находится false … Проверим:
var value = new Boolean(false); alert( value ); // выводит false, все ок.. if (value) < alert( true ); // ..но тогда почему выполняется alert в if . >
Дело в том, что new Boolean – это не примитивное значение, а объект. Поэтому в логическом контексте он преобразуется к true , в результате работает первый пример.
А второй пример вызывает alert , который преобразует объект к строке, и он становится «false» .
В JavaScript вызовы new Boolean/String/Number не используются, а используются простые вызовы соответствующих функций, они преобразуют значение в примитив нужного типа, например Boolean(val) === !!val .
Итого
- В логическом контексте объект – всегда true .
- При строковом преобразовании объекта используется его метод toString . Он должен возвращать примитивное значение, причём не обязательно именно строку.
- Для численного преобразования используется метод valueOf , который также может возвратить любое примитивное значение. У большинства объектов valueOf не работает (возвращает сам объект и потому игнорируется), при этом для численного преобразования используется toString .
Полный алгоритм преобразований есть в спецификации ECMAScript, смотрите пункты 11.8.5, 11.9.3, а также 9.1 и 9.3.
Заметим, для полноты картины, что некоторые тесты знаний в интернет предлагают вопросы типа:
Если вы запустите эти выражения в консоли, то результат может показаться странным. Подвох здесь в том, что если фигурные скобки <. >идут не в выражении, а в основном потоке кода, то JavaScript считает, что это не объект, а «блок кода» (как if , for , но без оператора просто группировка команд вместе используется редко).
А если команду изъять, то будет пустой блок <> , который ничего не делает. Два примера выше как раз содержат пустой блок в начале, который ничего не делает. Иначе говоря:
<>[0] // то же что и: [0] <> + <> // то же что и: + <>
То есть, такие вопросы – не на преобразование типов, а на понимание, что если < . >находится вне выражений, то это не объект, а блок.