Ну, как EMCAScript реализации, Javascript будет следовать Аннотация Relational алгоритм сравнения, как это определено в разделе ECMA-262 11.8.5.
Во-первых, Javascript будет применяться к обоим операнды внутренний оператор ToPrimitive
, который должен возвращать элементарное значение (неопределенными, булево, строку, нуль или номер) на основе аргументов, переданных Это. Если примитивное значение передается в ToPrimitive
, возвращаемое значение - это значение аргумента, переданное оператору, если он является внутренним методом, который вызывается всеми объектами в Javascript, это [[DefaultValue]]. Этот метод отвечает за возврат примитивного типа, который представляет объект. В зависимости от типа кода этот метод может вызывать либо методы toString
, либо valueOf
объекта.
Например:
var x = {valueOf: function() { return 3; }};
console.log(x > 2); // true
console.log(x < 1); // false
console.log(x == 3); // true
Каким Javascript решить, какой метод он должен вызвать? Ну, оператор ToPrimitive
может получить необязательный параметр, он используется, чтобы отдать предпочтение определенному типу, например. Number
или String
. Если передано Number
, сначала будет вызываться метод valueOf
, если этот метод не существует в объекте или не возвращает примитивный тип, тогда вызывается toString
. Если передается String
, происходит обратное: toString
вызывается первым, если он не существует в объекте и не возвращает примитивное значение, вызывается valueOf
.
Вот почему в приведенном выше фрагменте я могу свободно сравнивать объект и примитивный тип. Очень важно понимать при сравнении.
После этого, если оба операнда Strings
Javascript будет следовать некоторому интересному и конкретному алгоритму, связанному с Unicode Standard, проверяя значения кодовых точек. В противном случае Javascript будет отличать оба операнда до Number
, а их математическое значение сравнивается. Заметим, что если один из них равен NaN, сравнение составляет undefined, который будет false в сообщении if
.
Некоторых примеры:
// true => ToNumber(true) > ToNumber(false)
console.log(true > false);
// true => ToNumber("5") < ToNumber(10)
console.log("5" < 10);
// false ToNumber(ToPrimitive(obj, Number)) == ToNumber(10)
console.log(({valueOf: function() { return 10}}) > 10);
// false, it's not related to the length of the strings,
// the code point value of each char is used to evaluate the comparison
console.log('Hello worlds' > 'hello');
Надеются, что это помогает прояснить кой-что.
Я предполагаю тип принуждения? – Joseph