Javascript 在很多地方会出现字符串隐私转换,需要特别留意。
1、Object.keys(array) 返回字符串数组
示例:
// indexs will be ["0", "1", "2"]
indexs = Object.keys([1, 2, 3])
如果要想数字索引,使用 array.map :
// indexs will be [0, 1, 2]
indexs = [1, 2, 3].map((_, i) => i);
2、字符串和数值比较
假设 str 是一个字符串, value 是一个数值。当比较 str 和 value 时(包括 >, <, >=, <=, ==, !=),字符串 str 会被转化为一个数值,再与 value 进行比较。如果 str 不能转为一个有效的是数值(实际被转为了 NaN ),此时比较总是返回 false。
console.log("123" == 123);
// 输出: true,字符串 "123" 被转换为数值 123,123 等于 123
console.log("10" > 5);
// 输出: true,字符串 "10" 被转换为数值 10,并且 10 > 5
console.log("5" < 10);
// 输出: true,字符串 "5" 被转换为数值 5,并且 5 < 10
console.log("3.14" >= 3);
// 输出: true,字符串 "3.14" 被转换为数值 3.14,并且 3.14 >= 3
console.log("12a" < 123);
// 输出: false,字符串 "12a" 不能被解析为有效的数值,所以被转换为 NaN,
// 任何与 NaN 的比较都返回 false
console.log("true" == 0);
// 输出: false,字符串 "true" 不能被解析为有效的数值,所以被转换为 NaN,
// NaN 与任何值的相等性比较都返回 false
这里面最容易搞错的的是 "123" == 123。
3、array.indexOf(v) 中字符串不会被隐式转换
在计算 array.indexOf(v)时,使用的是绝对等于===
,因此字符串和数值不会被认为相等:
const array = [2, 9, 9, NaN];
array.indexOf(9); // 1
array.indexOf(7); // -1
array.indexOf(NaN); // -1
需要注意它和下面的 indexOf(array, v)
的区别,由于使用了==比较符,数值和字符串可能会被认为相等:
const indexOf = (array, v) => array.findIndex(item => item == v);
4、array.includes(v) 中字符串不会被隐式转换
array.includes 和 array.indexOf 类似,字符串不会被隐式转换。不过 array.includes 支持 NaN 值的查找:
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
["1", "2", "3"].includes(3); // false
Q. E. D.