javascript 的隐式转换和字符串可能引起的 bug

作者: , 共 1789 字 , 共阅读 0

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.

户外 » 戏水, 浆板, 昆玉河
周六晚上在颐和园南如意门外昆玉河,也是京密引水渠上,划桨板和游泳。车停在昆明湖东路的红绿灯路口附近(无正式车位,停路边空位),走到河边大约 100 米。
最近玩水比较多,顺便关注了北京河流的水质。有些地方,一看就知道水质不好,但有些地方看着挺清的,其实水质也可能不好。最终找到了北京市生态环境局公布的北京市河流水质状况北京市湖泊水质状况