【发布时间】:2017-07-09 18:54:13
【问题描述】:
我只是创建了一个函数,该函数将 JSON.stringify 输入,但也会在数字输入上检测 NaN,但由于以下原因不想使用 typeof。输入可以是number、boolean 或string。仅此而已。
我已经到了NaN !== NaN的情况,所以:
if (input !== input || input === Infinity || input === -Infinity) {
output = input.toString();
} else {
output = JSON.stringify(input);
}
我这样做是因为JSON.stringify() 在值为NaN 或Infinity 时返回"null"。
我知道使用typeof 和toString() 这很容易实现,但是一些性能测试表明IE11 下的typeof 确实很慢(在我们的情况下比JSON.stringify() 慢4-5 倍),我们需要在这里关注 IE11。
我想知道val !== val是否还有更多情况。
这里有一个性能测试:https://jsperf.com/typeof-vs-nan-nan2 没有使用 SO ,因为它们似乎在服务器端运行代码,因为那里的 IE 性能与其他地方一样好。不可能的事。
本地测试是:
var mockdata = [];
function notToJson(val) {
return val !== val || val === Infinity || val === -Infinity;
}
for (var i = 0; i < 500000; i++) {
var n = Math.floor(Math.random()*1000000);
if (Math.random()>0.5) {
n = n.toString();
} else if (Math.random()>0.5) {
if (Math.random()>0.5) {
n = NaN;
} else {
if (Math.random()>0.5) {
n = Infinity;
} else {
n = -Infinity;
}
}
}
mockdata.push(n);
}
console.time("typeof");
for (i = 0; i < 500000; i++) {
var res = typeof mockdata[i] === "string";
}
console.timeEnd("typeof");
console.time("notToJson");
for (i = 0; i < 500000; i++) {
res = notToJson(mockdata[i]);
}
console.timeEnd("notToJson");
console.time("toString");
for (i = 0; i < 500000; i++) {
res = mockdata[i].toString();
}
console.timeEnd("toString");
console.time("JSON.stringify");
for (i = 0; i < 500000; i++) {
res = JSON.stringify(mockdata[i]);
}
console.timeEnd("JSON.stringify");
console.time("Full typeof");
for (i = 0; i < 500000; i++) {
res = typeof mockdata[i]==="string"?JSON.stringify(mockdata[i]):mockdata[i].toString();
}
console.timeEnd("Full typeof");
console.time("Full notToJson");
for (i = 0; i < 500000; i++) {
res = notToJson(mockdata[i])?mockdata[i].toString():JSON.stringify(mockdata[i]);
}
console.timeEnd("Full notToJson");
Chrome 输出是:
但是 IE11 的输出是:
我注意到mockdata 的字符串越少,typeof 的性能明显提高(谈论 IE11)。
【问题讨论】:
-
原因是IE11速度慢,你可以在问题中读到。
-
@George——但这是针对不同的对象。
-
请使用
<>sn-p 编辑器发布minimal reproducible example -
@George——但它们是两个不同的值。 OP 正在寻找的是当一个值不等于自身时,
var a = {}; a === a为真,但var b = NaN; b === b为假。 -
使用Number.isNaN?当使用 JSON.stringify 时,typeof 真的那么慢吗? PS:还有更深奥的情况,在某种程度上,
val !== val。我能想到的一种结构是在查找之间执行任何类型的代码时,例如对于 getter、隐式 valueOf 调用等。
标签: javascript types nan