Всегда ли 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 (i.e без явного вызова toString)?

3 ответов


оператор + для объектов Date использует toString not valueOf. Также, если valueOf возвращает непримитивное значение, то метод toString вызывается next. (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 конструктор и строковые методы при литье this объект в строку
  • на RegExp конструктор
  • на Error конструкторы
  • множество других функций, не указанных EcmaScript, но в DOM или где-то еще, например alert, XMlHTTPRequest::open, querySelector, ...

есть ли какое-либо выражение

Да. Вот пример, который будет использовать toString:

alert({
    toString: function () {
        return "4";
    },
    valueOf: function () {
        return 6;
    }
});  // alerts "4"