Как вы заметили, это один из входных данных алгоритма абстрактного реляционного сравнения . Его единственная цель состоит в том, чтобы определить, какой операнд сначала передает алгоритм сравнения в ToPrimitive: один слева ( leftFirst = true) или один справа ( leftFirst = false) , Причина в том, что Абстрактное реляционное сравнение всегда выполняет сравнение <
, но оно также используется при оценке выражений >
(с обращенными операндами). Поэтому при обработке >
необходимо сначала указать ToPrimitive для правого операнда.
Вы можете увидеть, как он используется на первом шаге алгоритма:
- Если флаг LeftFirst равен true , тогда
- Пусть будет px ? ToPrimitive ( x , номер подсказки).
- Пусть будет py ? ToPrimitive ( y , номер подсказки).
- Иначе,
ПРИМЕЧАНИЕ. Порядок оценки необходимо изменить на противоположный, чтобы сохранить оценку слева направо. - Пусть py будет? ToPrimitive ( y , номер подсказки).
- Пусть будет px ? ToPrimitive ( x , номер подсказки).
Также в описании:
Используется флаг контролировать порядок выполнения операций с потенциально видимыми побочными эффектами при x и y . Это необходимо, потому что ECMAScript определяет оценку выражений слева направо.
Например, если вы посмотрите на операции <
и >
, операцию <
делает:
Пусть r будет результатом выполнения абстрактного реляционного сравнения lval .
При использовании значения по умолчанию leftFirst , что составляет true
. Таким образом, lval
передается через ToPrimitive до rval
.
Но операция >
делает:
Пусть r будет результатом выполнения абстрактного реляционного сравнения rval <<em> lval с LeftFirst , равным false .
Обратите внимание, что это rval < lval
, а не lval > rval
. Но он использует leftFirst = false
, потому что важно, чтобы операнд right был передан через ToPrimitive перед левым операндом, поскольку реальная операция - lval > rval
, поэтому lval
следует сначала пройти через ToPrimitive.
В комментарии вы сказали:
Большое спасибо, я узнал, почему, если оператор <
равен LeftFirst true
тогда почему <=
также не LeftFirst true
и почему, если оператор >
равен LeftFirst false
, оператор >=
также не LeftFirst false
Это определенно немного сбивает с толку. Причина, по которой <
и <=
не совпадают (а >
и >=
не совпадают) заключается в том, что операторы <=
/ >=
инвертируют результат абстрактного реляционного сравнения (AR *) 1284 *). Итак:
lval < rval
делает:
let r = ARC(lval < rval, leftFirst = true);
return r === undefined ? false : r; // Returns what ARC returned (but
// turns `undefined` into `false`)
lval <= rval
делает
let r = ARC(rval < lval, leftFirst = false);
return r === undefined ? true : !r; // Returns the *inverse* of what ARC
// returned (and turns `undefined`
// into `true`)
lval > rval
делает:
let r = ARC(rval < lval, leftFirst = false);
return r === undefined ? false : r; // Returns what ARC returned (but
// turns `undefined` into `false`)
lval >= rval
делает:
let r = ARC(lval < rval, leftFirst = true);
return r === undefined ? true : !r; // Returns the *inverse* of what ARC
// returned (and turns `undefined`
// into `true`)
A заключительная нота , давайте рассмотрим это:
const obj = {
get lval() {
console.log("obj.lval was evaluated");
return {
valueOf() {
console.log("lval was passed through ToPrimitive");
return 42;
}
};
},
get rval() {
console.log("obj.rval was evaluated");
return {
valueOf() {
console.log("rval was passed through ToPrimitive");
return 24;
}
};
}
};
console.log("Using >");
const result1 = obj.lval > obj.rval;
// "obj.lval was evaluated"
// "obj.rval was evaluated"
// "lval was passed through ToPrimitive"
// "rval was passed through ToPrimitive"
console.log(result1);
// true
console.log("Using <");
const result2 = obj.lval < obj.rval;
// "obj.lval was evaluated"
// "obj.rval was evaluated"
// "lval was passed through ToPrimitive"
// "rval was passed through ToPrimitive"
console.log(result2);
// false
.as-console-wrapper {
max-height: 100% !important;
}
Вывод, который вы видите из этого:
Использование> obj.lval было оценено obj.rval было оценено lval был передан через ToPrimitive rval был передан via ToPrimitive true Использование
Вот что происходит для создания этого вывода для >
:
- Выражение
obj.lval > obj.rval
оценивается - Операторный алгоритм
>
выполняется: - Он оценивает
lval = obj.lval
(шаги 1 и 2), что приводит к выводу "obj.lval was evaluated"
- Он оценивает
rval = obj.rval
(шаги 3 и 4), что вызывает "obj.rval was evaluated"
вывод - Он вызывает AR C (Шаг 5):
ARC(obj.rval < obj.lval, leftFirst = false)
- AR C получает
obj.rval
как x
и obj.lval
как y
- AR C видит leftFirst =
false
и так: py = ToPrimitive(y)
(шаг 2.b), что приводит к выводу "lval was passed through ToPrimitive"
px = ToPrimitive(x)
(шаг 2. c), что приводит к выводу "rval was passed through ToPrimitive"
- AR C возвращает
false
- Оператор
>
инвертирует возвращаемое значение AR C и возвращает true
Вот что происходит для создания последующего вывода для <
:
- Выражение
obj.lval < obj.rval
оценивается - Алгоритм оператора
<
выполняется: - Он оценивает
lval = obj.lval
(шаги 1 и 2), что вызывает "obj.lval was evaluated"
output - Оценивает
rval = obj.rval
(шаги 3 и 4), что приводит к выводу "obj.rval was evaluated"
- Вызывает AR C (шаг 5):
ARC(obj.lval < obj.rval)
(leftFirst) по умолчанию true) - AR C получает
obj.lval
как x
и obj.rval
как y
- AR C видит leftFirst = * 1 260 * и так оно и есть:
px = ToPrimitive(x)
(шаг 1.a), который вызывает вывод "lval was passed through ToPrimitive"
py = ToPrimitive(y)
(шаг 1.b), который вызывает "rval was passed through ToPrimitive"
output
- AR C возвращает
false
- Оператор
<
возвращает AR C возвращаемое значение, false