深入探討 Undefined

weixin_34370347發表於2018-10-23

原文:davidshariff.com/blog/javasc…

翻譯:瘋狂的技術宅

Undefined 這個概念聽起來很簡單,不過你知道應該怎樣檢查JavaScript中的變數或屬性是否真的存在嗎? 做這件事最好的方法是什麼? 我們如何涵蓋所有的邊界值? 要回答這些問題,首先讓我們來看看究竟什麼是undefined......

undefined概述

變數的值被賦予一個型別,JavaScript中有幾個內建的本地型別:

  1. Undefined
  2. Null
  3. Boolean
  4. String
  5. Number
  6. Object
  7. Reference
  8. etc…

首先看第一個,內建的Undefined型別只能有一個值,它稱為undefined。 這是一個原始值,只要宣告瞭變數,就會為其分配此undefined值,直到您以程式設計的手段為其分配不同的值。

此外,每當函式完成執行並返回一個沒有給定的值時,它預設返回undefined

var foo,
    bar = (function() {
        // do some stuff 
    }()),
    baz = (function() {
        var hello;
        return hello;
    }());

typeof foo; // undefined
typeof bar; // undefined
typeof baz; // undefined
複製程式碼

因此,當宣告一個變數但還未賦值時,它將被賦予undefined值。 我們還應該注意的是:undefined本身是一個在全域性範圍內可用的變數/屬性,它的值也是undefined

typeof undefined; // undefined

var foo;

foo === undefined; // true
複製程式碼

但是,全域性變數undefined並不是保留字,因此它可以被重新定義。 幸運的是,從ECMA 5開始,就不允許重新定義undefined了,但是在以前的版本和舊版瀏覽器中,可以執行以下操作:

typeof undefined; // undefined
undefined = 99;
typeof undefined; // number
複製程式碼

null到底代表了什麼?

先看下面的程式碼:

null == undefined // true
null !== undefined // true
複製程式碼

很多人對此都感到困惑,實際上很簡單。 nullundefined之間唯一真正的關係是:它們在型別強制過程中都判斷為false。

之所以所以 null == undefined // true 是因為 == 沒有執行嚴格的比較,因為在比較型別時使用 !== 更嚴格。 每當您把 null 看作是一個值時,它會始終以程式設計方式進行指定,並且在預設情況下從不設定。

訪問物件的屬性

當您嘗試使用物件上一個不存在的屬性時,也會得到undefined,如果您把不存在的屬性作為函式使用有時會引發錯誤。

var foo = {};

foo.bar; // undefined
foo.bar(); // TypeError
複製程式碼

如果您想分辨“有未定義值的屬性”和“根本不存在的屬性”這兩者,應該怎麼做呢?

使用typeof 或者 ===都會給你一個undefined的值。

使用in運算子能夠檢查物件中是否存在某個屬性:

var foo = {};

// undefined (這樣不好,bar從未在window物件中被宣告過)
typeof foo.bar;

// false (如果您不關心原型鏈,這樣用)
'bar' in foo;

// false (如果你關心原型鏈,就這樣用)
foo.hasOwnProperty('bar');
複製程式碼

應該用typeof還是in/hasOwnProperty?

這很顯然。一般來說,如果要測試是一個屬性否存在,那麼就用 in/hasOwnProperty,如果要檢查屬性或變數的值,則用 typeof

通過例子進行總結

檢查變數是否存在:

if (typeof foo !== 'undefined') {}
複製程式碼

檢查物件上的屬性是否存在,無論是否已經為它分配了值:

// 存在於物件上,同時也檢查原型
if ('foo' in bar) {}

// 直接存在於物件上,不檢查原型
if (bar.hasOwnProperty('foo')) {}
複製程式碼

檢查物件上是否存在屬性,並且屬性具有值集(真值或假)

var bar = {
    foo: false
}; 

if ('foo' in bar && typeof bar.foo !== 'undefined'){ 
    // bar.foo存在,並且它包含以程式設計方式分配的值
}
複製程式碼

相關文章