2017-02-20 141 views
0

我只是创建一个函数,将JSON.stringify输入,但也检测NaN数字输入,但不想使用typeof由于下述原因。输入可以是number,booleanstring。而已。在哪种情况下val!== val?

我已经达到了情况NaN !== NaN,所以:

if (input !== input || input === Infinity || input === -Infinity) { 
    output = input.toString(); 
} else { 
    output = JSON.stringify(input); 
} 

我做这种方式,因为JSON.stringify()回报"null"当值NaNInfinity

我知道,与typeoftoString()这是很容易实现,但一些性能测试表明,typeof IE11下是很慢(比JSON.stringify()慢4-5倍,我们的情况下),我们需要把重点放在IE11这里。

我想知道是否有更多的案例val !== val

在这里你有一个性能测试:https://jsperf.com/typeof-vs-nan-nan2 没有使用的SO之一,因为他们似乎运行的代码服务器端,因为那里的IE性能是一样好的地方。 Impossibru的事情。

本地测试:

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的输出是:

enter image description here

但IE11输出为:

enter image description here

我已经注意到,少串mockdata已经,typeof的性能显着提高(谈论IE11)。

+0

*但由于原因*不想使用typeof,原因是什么? –

+1

原因是它在IE11中很慢,因为你可以在这个问题中读到。 – Aloso

+0

'{}!== {}'这是我唯一能够想到的其他东西,其中'val!== val' – George

回答

2

这里有一些情况下,val !== val返回true:当对象不同

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 
+0

完美。正是我需要的。 –