在哪些情况下 val !== val? (将变量与自身进行比较)
In which cases val !== val? (compare a variable with itself)
我只是在创建一个函数,它将 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()
returns "null"
当值为 NaN
或 Infinity
.
我知道使用 typeof
和 toString()
这很容易实现,但是一些性能测试表明 typeof
在 IE11 下真的很慢(比 IE11 慢 4-5 倍) JSON.stringify()
在我们的情况下),这里需要重点关注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)。
以下是 val !== val
returns 正确的一些情况:
console.log({} !== {}); // true
console.log(new Date() !== new Date()); // true
console.log(new String("") !== new String("")); // true
仅当对象不同时适用:
var a = b = {}; // now they are equal
console.log(a !== b); // false
它也发生在 Symbols(ES6 特性):
console.log(Symbol() !== Symbol()); // true
我要自己回答这个问题,因为我不喜欢没有答案的问题。
请注意问题是如何谈论 val
的。我的意思是给一个变量赋值,然后比较变量和它自己。 不要创建两个不同的变量并比较它们。
根据我自己的测试,val !== val
仅当val = NaN
时,所以:
var val = NaN;
console.log("val !== val:", val !== val);
原因就在这里:Why is NaN not equal to NaN?
我只是在创建一个函数,它将 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()
returns "null"
当值为 NaN
或 Infinity
.
我知道使用 typeof
和 toString()
这很容易实现,但是一些性能测试表明 typeof
在 IE11 下真的很慢(比 IE11 慢 4-5 倍) JSON.stringify()
在我们的情况下),这里需要重点关注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)。
以下是 val !== val
returns 正确的一些情况:
console.log({} !== {}); // true
console.log(new Date() !== new Date()); // true
console.log(new String("") !== new String("")); // true
仅当对象不同时适用:
var a = b = {}; // now they are equal
console.log(a !== b); // false
它也发生在 Symbols(ES6 特性):
console.log(Symbol() !== Symbol()); // true
我要自己回答这个问题,因为我不喜欢没有答案的问题。
请注意问题是如何谈论 val
的。我的意思是给一个变量赋值,然后比较变量和它自己。 不要创建两个不同的变量并比较它们。
根据我自己的测试,val !== val
仅当val = NaN
时,所以:
var val = NaN;
console.log("val !== val:", val !== val);
原因就在这里:Why is NaN not equal to NaN?