面试题答案
一键面试不同类型数据比较规则
- 字符串与数字比较:
- 字符串会被转换为数字再进行比较。例如:
console.log('5' > 3); // true,'5' 转换为数字5,5 > 3为true console.log('abc' > 3); // false,'abc' 转换为NaN,NaN与任何值比较都为false
- 布尔值与其他类型比较:
- 布尔值
true
转换为1,false
转换为0再进行比较。例如:
console.log(true > 0); // true,true转换为1,1 > 0为true console.log(false < 1); // true,false转换为0,0 < 1为true
- 布尔值
- 对象与其他类型比较:
- 对象首先会调用
valueOf()
方法,如果返回的不是原始值,再调用toString()
方法,将返回值转换为原始值后进行比较。例如:
const obj = { valueOf: function() { return 5; } }; console.log(obj > 3); // true,obj调用valueOf返回5,5 > 3为true const obj2 = { toString: function() { return '5'; } }; console.log(obj2 > 3); // true,obj2调用toString返回'5','5'转换为5后5 > 3为true
- 对象首先会调用
对关系表达式性能的影响
- 类型转换开销:由于不同类型数据比较时需要进行类型转换,这会带来额外的性能开销。例如,频繁地将字符串转换为数字进行比较,比直接进行数字之间的比较要慢。如以下代码片段,在大量循环中体现性能差异:
let start = Date.now(); for (let i = 0; i < 1000000; i++) { '5' > 3; } let end = Date.now(); console.log(`字符串与数字比较耗时: ${end - start} ms`); start = Date.now(); for (let i = 0; i < 1000000; i++) { 5 > 3; } end = Date.now(); console.log(`数字与数字比较耗时: ${end - start} ms`);
- 复杂对象转换开销:对象在比较时涉及
valueOf()
和toString()
方法调用,如果对象没有重写这些方法,默认的转换可能不符合预期,而且多次调用这些方法也会带来性能损耗。例如在一个包含大量对象的数组中进行比较操作:
这里对象比较时默认转换操作可能导致性能不佳,如果对象重写了合适的const arr = []; for (let i = 0; i < 10000; i++) { arr.push({}); } let start = Date.now(); for (let i = 0; i < arr.length; i++) { arr[i] > 3; } let end = Date.now(); console.log(`对象与数字比较耗时: ${end - start} ms`);
valueOf()
或toString()
方法,性能可能会有所改善,但仍可能因多次方法调用产生一定开销。