JS运算符中我认为需要注意的细节

324 阅读2分钟

加减号处理字符串,对象的不同

加加/减减

let num = 1;
const result = ++num + 2; // 4
// 等价于
// num += 1;
// const result = num + 2;
let num = 1;
const result = num++ + 2 // 3
// 等价于 
// result = num + 2;
// num += 1;

减减同样处理

加号遇到字符串是我们很常见的情况

  • 如果两个操作数都是字符串,则将第二个字符串拼接到第一个字符串后面
  • 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,再将两个字符串拼接再一起。如果有任一操作数是对象、数值或布尔值,则调用它们的 toString() 方法以获取字符串,然后再应用前面的关于字符串的规则。对于 undefined 和 null ,则调用String()函数,分别获取 "undefined" 和 "null"。 JavaScript高级程序设计

平时使用多了不会太在意,其实内部调用的 toString() 方法,所以我们可以通过修改 toString() 方法来改变运算后的结果

const obj = {
  toString: () => "test",
};
console.log("1" + obj); // '1test'

对于减号来说,我们可能第一印象也会把加号的这些规则套用,但其实不然

  • 如果有任一操作数是字符串、布尔值、null 或 undefined ,则先再后台使用 Number() 将其转换为数值,然后再根据前面的规则执行教学运算。如果转换结果是 NaN,则减法计算的结果是 NaN。
  • 如果有任一操作数是对象,则调用它们的 valueOf() 方法取得表示它的数值。如果该值是 NaN ,则减法计算的结果是 NaN 。如果对象没有 valueOf() 方法,则调用其 toString() 方法,然后再将得到的字符串转为数值 JavaScript高级程序设计

不难看出相对于加法运算遇到字符串时更倾向于将结果转换为字符串不同,减法更倾向于将结果转换为数值

并且我感觉针对这一点,语言在设计的时候考虑到了非数值非字符串的操作数遇到运算时该如何处理,valueOf针对数值,toString针对字符串,仅代表个人观点。

在进行比较时,往往会将比较双方先数值化,再进行比较

'a' < 1; // false

这里字符串a会先被转为NaN,涉及比较NaN都返回false,所以会出现

NaN > 1; // false
NaN <= 1; // false

比较字母字符串或数值字符串时会按照编码逐一字符比较大小,如:

'a' > 'B'; // true, a编码97, B编码66
'a' > 'b'; // false,a编码97, b编码98
'12' > '3'; // false1编码493编码51
'ab' > 'aa'; // true,前面相同,后续逐一比较