以下所用测试代码可以访问 RunJS 查看

undefined 与 null

如果定义一个变量却不赋值,则其默认等于 undefined

var foo;
console.log(foo); // undefined

也可以对其赋值 undefined

var undef = undefined;
console.log(undef); // undefined

调用函数时,传入的参数少于所需参数,未传入的参数也为 undefined

bar(1, 2);
function bar(a, b, c){
    console.log(a, b, c); // 1, 2, undefined
}

使用 new Array(n) 的形式初始化一个长度为 n 的数组时,数组中的值默认为 undefined

var arr = new Array(3);
console.log(arr); // [undefined × 3]

这里要注意使用 var arr = new Array(1, 2, 3)var arr = [3] 与上述初始化方法的区别。

获取某对象不存在的属性或数组中不存在的值时,也会返回 undefined

var element = {};
console.log(element.nonAttr);  // undefined

var arr = [];
console.log(arr[1]);  // undefined

var obj = new Object();
console.log(obj.nonAttr);  // undefined

直接获取 DOM 元素非原生属性或未赋值的原生属性时,会返回 undefined

<div id="1" nonAttr="attr"></div>

<script>
    console.log(document.getElementById("1").width);    // undefined            
    console.log(document.getElementById("1").nonAttr);  // undefined
</script>

将一个不存在的 DOM 对象赋值给一个变量时,该变量为 null

var foo = document.getElementById("notExists");
console.log(foo); // null

也可以将变量赋值为 null

var nullVal = null;
console.log(nullVal); // null

对于 undefinednull,由于前者是由后者派生而出的,所以其二者使用 == 比较时是相等的,因而若要对二者进行区分,则需要使用 ===typeof

undefined == null;                   // true
undefined === null;                  // false
typeof(undefined) == typeof(null);   // false

NaN

NaN( Not a Number ),表示非数字。任何值都不与 NaN 相等,甚至是它自己;

1          == NaN   // false
""         == NaN   // false
" "        == NaN   // false
"abc"      == NaN   // false
[]         == NaN   // false
{}         == NaN   // false
null       == NaN   // false
undefined  == NaN   // false
NaN        == NaN   // false

我们可以使用 isNaN 来判断一个值是否为 NaN

isNaN( 1 )            // false
isNaN( "" )           // false
isNaN( " " )          // false
isNaN( "abc" )        // true
isNaN( [] )           // false
isNaN( {} )           // true
isNaN( null )         // false
isNaN( undefined )    // true
isNaN( NaN )          // true

注意,由于部分非数字的 isNaN() 结果也为 false,所以若要判断一个值是否为数字,需要使用如下方法:

isNumber( 1 )          // true
isNumber( "" )         // false
isNumber( " " )        // false
isNumber( "abc" )      // false
isNumber( [] )         // false
isNumber( {} )         // false
isNumber( null )       // false
isNumber( undefined )  // false
isNumber( NaN )        // false

// 判断一个值是否为数字
function isNumber(value){
    return !isNaN(parseFloat(value));
}

注:parseIntparseFloat 方法在转换失败时会返回 NaN

提示:isNaN() 函数通常用于检测 parseFloat() 和 parseInt() 的结果,以判断它们表示的是否是合法的数字。当然也可以用 isNaN() 函数来检测算数错误,比如用 0 作除数的情况。

「与」运算:&&

多个布尔类型相「与」,若其中存在一个及以上的 false,则结果为 false,否则为 true。且在「与」运算中存在「短路」,即遇到第一个 false 之后的内容不会运行。

true && true  && false && true   // false
true && true  && true  && true    // true
true && false && i++   && j--     // false, i 和 j 的值不会变化

问题来了,如果这里参与「与」运算的不全是布尔类型呢?

true && 11 && "string" && {}   // 输出什么?

在讨论这个问题之前,我们先看一看以下两组变量的值:

0         == true     // false
-123      == true     // false
123       == true     // false
""        == true     // false
"string"  == true     // false
[]        == true     // false
[1,2,3]   == true     // false
null      == true     // false
undefined == true     // false
NaN       == true     // false
{}        == true     // Uncaught SyntaxError
Boolean( 0 )          // false
Boolean( -123 )       // true
Boolean( 123 )        // true
Boolean( "" )         // false
Boolean( "string" )   // true
Boolean( [] )         // true
Boolean( [1,2,3] )    // true
Boolean( null )       // false
Boolean( undefined )  // false
Boolean( NaN )        // false
Boolean( {} )         // true

然后我们做如下测试:

true  && false                // false
true  && NaN                  // NaN
true  && null                 // null
true  && []                   // []
0     && []                   // 0
true  && "AAA" && undefined   // undefined
true  && "AAA" && "BBB"       // BBB
false && "AAA" && "BBB"       // false

这里我们发现,「与」运算的结果并不一定是布尔值。结合上述 Boolean(xx) 形式结果,可以得出猜测:「与」运算的结果取决于第一个Boolean(xx) 转换结果false 的值;若全部皆为 true,则结果为最后一个值。

以之前的问题为例,对于 true && 11 && "string" && {},我们可以将其转换为:

true && Boolean(11) && Boolean("string") && Boolean({})

由于这四个值的结果均为 true,因而 true && 11 && "string" && {} 的结果即为最后一个值,即:{}

同理,我们可以得知,true && 0 && "string" && {}true && [] && "" && null 的值分别为:0""

「或」运算:||

同 && 「与」运算类似,「或」运算的结果也不一定为布尔类型,其结果取决于第一个Boolean() 结果true 的值,若全部为 false,则结果为最后一个元素的值,如以下例子:

true  || false                // true
true  || NaN                  // true
true  || null                 // true
true  || []                   // true
0     || []                   // []
true  || "AAA" || undefined   // true
true  || "AAA" || "BBB"       // true
false || "AAA" || "BBB"       // "AAA"

参考:

  1. JS中Null与Undefined的区别 - 博客园

  2. 为什么 javascript 中 Boolean... - 百度知道

  3. JavaScript isNaN() 函数 - w3school


dailybird
1.1k 声望73 粉丝

I wanna.