Всегда ли valueOf переопределяет toString в JavaScript?
Есть ли какое-либо выражение, где методом toString объекта неявно вызывается переопределение его метода valueOf?
В приведенных ниже примерах значение valueOf всегда вызывается неявно (переопределяя toString).
"4" + {
toString: function () {
return "4";
},
valueOf: function () {
return 6;
}
}; // => "46", was expecting "44"
4 + {
toString: function () {
return "6";
},
valueOf: function () {
return 4;
}
}; // => 8
4 + {
toString: function () {
return 6;
},
valueOf: function() {
return "4";
}
}; // => "44"
то есть:
Можем ли мы написать выражение, где toString неявно вызывается через valueOf (т.е. без явного вызова toString)?
3 ответа
Оператор + для объектов Date использует toString, а не valueOf. Также, если valueOf возвращает не примитивное значение, тогда вызывается метод toString. (JavaScript - полное руководство, раздел 3.14). Используя ваш пример:
var result = "4" + {
toString: function () {
return "4";
},
valueOf: function () {
return this; // returning an object, not a primitive
}
};
Результат сейчас 44.
Есть ли какое-либо выражение, где методом toString объекта неявно вызывается переопределение его метода valueOf?
Да, это случается всякий раз, когда ToString
операция применяется к объекту, используя DefaultValue
процедура с .toString()
до .valueOf()
,
Однако в ваших примерах вы использовали только оператор сложения, который является исключением из стандартного поведения. Поскольку он не только объединяет строки, но и суммирует числа, он всегда использует valueOf
на обоих операндах перед проверкой, являются ли они строками. Смотрите примечание 1:
В вызовах ToPrimitive на этапах 5 и 6 подсказка не предоставляется. Все нативные объекты ECMAScript, кроме объектов Date, обрабатывают отсутствие подсказки, как если бы был указан номер подсказки; Объекты Date обрабатывают отсутствие подсказки, как если бы была указана строка подсказки. Хост-объекты могут обрабатывать отсутствие подсказки другим способом.
Итак, какие операции неявно используют ToString
вместо намека ToPrimitive
? Вот несколько примеров:
- Все об именах собственности:
in
оператор, обозначение в скобках,Object.getOwnPropertyDescriptor
,Object.defineProperty
,hasOwnProperty
… - Функции, ожидающие строки в качестве аргументов:
parseInt
,parseFloat
,encodeURI[Component]
,decodeURI[Component]
,[un]escape
,Array::join
,String::[last]indexOf
,RegExp::exec
Function
конструкторArray::sort
функция сравнения алгоритма по умолчаниюString
методы конструктора и String при приведенииthis
возражать против строкиRegExp
конструкторError
конструкторы- Множество других функций, не указанных в EcmaScript, но в DOM или где-то еще, например
alert
,XMlHTTPRequest::open
,querySelector
…
Есть ли выражение
Да. Вот пример, который будет использовать toString
:
alert({
toString: function () {
return "4";
},
valueOf: function () {
return 6;
}
}); // alerts "4"