当>
和<
之类的比较运算符输入为两个字符串值时,它们返回Boolean
值。
我尝试了一些示例:
/* String vs String */
console.log('firstName' < 'lastname'); // true
console.log('firstName' < 'Firstname'); // false
console.log('!firstName' < 'lastname'); // true
console.log('!firstName' < 'Firstname'); // true
console.log('!firstName' < '!Firstname'); // false
console.log('!firstName' < '_!Firstname'); // true
console.log('@!firstName' < '_!Firstname'); // true
console.log('@!firstName' < '2_!Firstname'); // false
/* String vs Number */
console.log('@!firstName' < 2); // false
console.log('@!firstName' < -1); // false
/* String vs Special Numbers */
console.log('@!firstName' < Infinity); // false
console.log('@!firstName' < -Infinity); // false
console.log('@!firstName' < -Infinity + Infinity); // false
/* String vs NaN */
console.log('@!firstName' < NaN); // false
console.log(NaN.toString()); // "NaN"
console.log('@!firstName' < "NaN"); // true
/* String vs Arrays */
console.log('firstName' < [Infinity, -Infinity]); // false
console.log('firstName' < ['Firstname', Infinity, -Infinity]); // false
console.log('firstName' < ['2_Firstname', Infinity, -Infinity]); // false
我真的很想知道JavaScript如何真正评估这些表达式。在上面的示例中,我发现这是最令人着迷的console.log('@!firstName' < Infinity); // false
。
所以,我的问题是:
如何使用“ 大于”和“ 在这些情况下,JavaScript中的运算符少于”运算符(来自以上示例):
答案 0 :(得分:2)
如上所述,正式规范是在标准http://www.ecma-international.org/ecma-262/7.0/#sec-abstract-relational-comparison中,用外行的话来说,逻辑是这样的:
将两个字符串都拆分为16位代码单元,并对其进行数值比较。请注意,代码单位!=字符,例如"cafè" < "cafè"
是true
(真的)。
将两者都转换为数字。如果其中之一是NaN
,请返回false
,否则请进行数值比较。 +0
和-0
被认为是相等的,+/-Infinity
比其他任何事物都大/小。
尝试将对象转换为基元,依次尝试[Symbol.toPrimitive]("number")
,valueOf
和toString
。如果我们有字符串,请继续执行1),否则继续进行2)。具体来说,对于数组,这将调用与toString
相同的join
。
答案 1 :(得分:0)
specification中描述了要采取的精确步骤,该步骤具体描述了比较的一侧(或双方)为NaN
或+Infinity
或-Infinity
。例如,对于px < py
,less-than operator调用抽象关系比较算法:
11.8.5抽象关系比较算法
(如果要比较的两个项目都不是字符串,则:)
让nx为调用ToNumber(px)的结果。因为px和py是原始值,所以评估顺序并不重要。
让ny是调用ToNumber(py)的结果。
如果nx是NaN,则返回undefined。
如果ny为NaN,则返回undefined。
如果nx和ny是相同的Number值,则返回false。
如果nx为+ 0,ny为−0,则返回false。
如果nx为-0且ny为+0,则返回false。
如果nx为+∞,则返回false。
如果ny为+∞,则返回true。
如果ny为-∞,则返回false。
如果nx为-∞,则返回true。
如果nx的数学值小于ny的数学值(请注意,这些数学值都是有限的且不都是零),则返回true。否则,返回false。
否则,px和py都是字符串
如果py是px的前缀,则返回false。 (如果q可以是将p和其他一些String r连接在一起的结果,则String值p是String值q的前缀。请注意,任何String都是其自身的前缀,因为r可能是空String。)
如果px是py的前缀,则返回true。
让k是最小的非负整数,以便px内k处的字符与py内k处的字符不同。 (必须有一个k,因为String都不是另一个的前缀。)
让m为整数,它是px内第k位字符的代码单位值。
让n为整数,它是py中位置k处字符的代码单位值。
如果m
当两个要比较的项目都是字符串时,它有效地导致每个字符的代码点都被比较。例如,'firstName' < 'lastname'
是因为f
(102)的字符代码小于l
(108)的字符代码。对于'!firstName' < 'Firstname'
,!
(33)的字符代码比F
(70)的字符代码小,因此其结果也等于true
。有关实现的示例,请参见以下代码段:
function compare(left, right) {
for (let i = 0; i < left.length; i++) {
const c1 = left[i].charCodeAt();
const c2 = right[i].charCodeAt();
if (c1 !== c2) {
console.log('Char code comparision:', c1 < c2, '< comparison:', left < right);
break;
}
}
}
/* String vs String */
compare('firstName', 'lastname'); // true
compare('firstName', 'Firstname'); // false
compare('!firstName', 'lastname'); // true
compare('!firstName', 'Firstname'); // true
compare('!firstName', '!Firstname'); // false
compare('!firstName', '_!Firstname'); // true
compare('@!firstName', '_!Firstname'); // true
compare('@!firstName', '2_!Firstname'); // false
答案 2 :(得分:0)
字符串,字符串比较基于Unicode顺序(a大于A)。
字符串,数字比较首先将字符串转换为数字,然后再进行比较(与无穷大相同)。
字符串,数组比较首先将数组转换为字符串,然后如上所述进行比较。