一、不是值的值
1、null 和 undefined
null类型只有一个值,即null。 undefined类型也只有一个值,即undefined。两者既属于类型也是值。
null:空值,或者没有值;
undefined:没有定义的值,即从未赋过值;
其中null不是标识符,而undefined是一个标识符。所以可以当做变量来使用(即可以赋值)。
在非严格模式下
var undefined = 1;//给undefined赋值为1
在严格模式下允许在局部给undefined赋值
(function(){
let undefined = 2;
console.log(undefined);//2
}())
上述例子通过IIFE(立即执行函数表达式)生成一个局部作用,在作用域内修改undefined值。
但!永远不要修改undefined值,这会带来很多未知的麻烦。
2.void
通过void运算符可以得到undefined值;
var a=1;
console.log(void a);//undefined
当我们需要将一些值设为undefined时就用的到void.
比如在等待时,我们通常会设置一个setTimeout()来实现一些等待时的操作,而setTimeout()函数会返回一个数值ID,有时候这会带来麻烦。如下:
setTimeout()函数会返回一个数值ID,为真值。这时我们就需要void来为我们扫除那些没必要的返回值。
function waiting(){
if( !ready ){
return setTimeout( waiting,1000 );
}
return signal;
}
if( waiting ){
//执行下一步
}
简单的设计思路:当没有准备好时(如还在加载中),执行一个setTimeout,一直等到准备完成时,返回出一个信号给下一步操作。但是上述代码在实际执行时却不同于预期,它会在第一次执行完setTimeout时就执行下一步。因为
setTimeout()函数会返回一个数值ID,为真值。这时我们就需要void来为我们扫除那些没必要的返回值。
function waiting(){
if( !ready ){
return void setTimeout( waiting,1000 );
}
return signal;
}
if( waiting ){
//执行下一步
}
二、特殊数字
1、NaN
NaN 全称‘not a number’,不是个数字。这样的翻译不是那么准确。
typeof( NaN );//number
通过typeof可以看到NaN是一个数值,所以应该叫‘不是数字的数字’可能会好些。
NaN是唯一一个非自反的值。
可以通过isNaN来查看一个数据是不是NaN。
isNaN( NaN );//true isNaN( 1/'aaa' );//true isNaN( 1 );//false isNaN( 'aaa' );//true????
NaN本质上是一个数,但是通过isNaN把字符串也归为NaN,这显然是不正确的。这个错误同typeof( null )返回object一样从js诞生存在到了现在。好在ES6中加了一个工具函数Number.isNaN(),它可以正确判断NaN。
Number.isNaN( NaN );//true
Number.isNaN( 1/'aaa' );//true
Number. isNaN( 1 );//false
Number. isNaN( 'aaa' );//fals
ES6之前的浏览器的polyfill如下
if (!Number.isNaN){
Number.isNaN = function(n) {
return (
typeof n === "number" &&& window.isNaN( n )
);
};
}
2、Infinity(无穷)
在js中可呈现的浮点数为(5e-324,1.798e+308)超过上限的都为Infinity,负值为-Infinity。
var a = 1/0;//Infinity
var b = -1/0;//-Infinity
a - 1 //Infinity
a + 1 //Infinity
a * 5 //Infinity
a / 5 //Infinity
a - a //NaN
a + a //Infinity
a * a //Infinity
a / a //NaN
计算结果一旦为无穷数就无法再通过计算得到有穷数。即可以从又穷变为无穷,但不能从无穷变为又穷。一旦涉及后者的操作,结果均为NaN。
3、+0,-0,0
在JavaScript中有一个常规的0,也叫作+0。也存在一个-0。
var a = 0 / -1; //-0
var b = 0 * -1;//-0
根据规范-0在字符串化时会返回"0"
a.toString(); //0
a + ''; //0
string( a ); //0
//json也是
JSON.stringify( a );//0
但是在字符串转换成数字时,得到的结果是准确的。
+ "-0"; //-0
Number( "-0" ); //-0
JSON.parse( "-0" ); //-0
它的比较操作也很怪异
0 === -0;//true
0 == -0; //true
0 > -0; //false
那么怎么区分-0和+0呢?
function isNegZero(n){
n = Number( n );
return (n === 0) && (1 / n === -Infinity);
}
isNegZero( -0 );//true
isNegZero( 0 );//false
4、绝对相等
通过上述我们了解到,NaN和自身不相等,而-0等于0。那么怎么判断两个数是否绝对相等呢?
好在ES6中新增了一个方法Object.is(),可以用来判断两个值是否绝对相等。
Object.is( 0, -0 );//false
Object.is( NaN, NaN );//true
Object.is( -0, -0 );//true
在ES6之前也可以写一个简单的判别函数
//关于两个值是否绝对相等
object1is = function(v1,v2){
if (v1 === 0 && v2 === 0){
return 1 / v1 === 1 / v2;
}
else if (v1 !== v1){
return v2 !== v2;
}
else return v1 === v2;
}
object1is( NaN, NaN );//true
object1is( NaN, 1 );//false
object1is( -0, +0 );//false
object1is( -0, -0 );//true
object1is( 6, 5 );//false