關於 JavaScript 中 null 的一切

来源:https://www.cnblogs.com/gopal/archive/2022/09/10/16675860.html
-Advertisement-
Play Games

原文地址:Everything about null in JavaScript 原文作者:Dmitri Pavlutin 譯者:Gopal JavaScript 有兩種類型:原始類型(strings, booleans, numbers, symbols)和對象 對象是一個複雜的數據結構。最簡單的 ...


原文地址:Everything about null in JavaScript

原文作者:Dmitri Pavlutin

譯者:Gopal

JavaScript 有兩種類型:原始類型(strings, booleans, numbers, symbols)和對象

對象是一個複雜的數據結構。最簡單的 JavaScript 對象是普通對象 —— 鍵和相關值的集合

let myObject = {
  name: 'Eric Cartman'
};

但是很多情況下不能創建一個對象。在這種情況下,JavaScript 提供了一個特殊的值 null —— 表示缺少對象

let myObject = null;

在這篇文章中,你將學習關於 JavaScript 中的 null 的一切: 它的含義,如何檢測它,nullundefined 之間的區別,以及為什麼大量使用 null 會造成代碼維護困難等

1.null 的概念

JavaScript 規範中這麼描述 null

null 是一種原始類型,表示有意不包含任何對象值

如果您看到 null(分配給變數或由函數返回),那麼在那個位置原本應該是一個對象,但由於某種原因,一個對象沒有創建

比如,函數 greetObject() 創建對象,但也可以在無法創建對象時返回 null:

function greetObject(who) {
  if (!who) {
    return null;
  }
  return { message: `Hello, ${who}!` };
}

greetObject('Eric'); // => { message: 'Hello, Eric!' }
greetObject();       // => null

當上面的函數中傳入一個字元串參數時,如預期的,函數返回一個對象 { message: 'Hello, Eric!' }

但是,函數中不傳任何參數時,該函數返回 null。返回 null 是合理的,因為 who 參數沒有值,導致 greeting 對象無法創建

1.1 null 的一個比較貼切的比喻

考慮關於 null 的一個比較貼切的比喻,你可以把變數想象成一個盒子。就像變數可以容納對象一樣,盒子也可以容納像茶壺等的物品

但一旦你收到一個盒子,打開它,什麼也沒有!有人弄錯了,給了你一個空盒子。該盒子不包含任何內容,或者換句話說,它包含一個 null

2. 如何去檢測 null

檢查 null 好方法是使用嚴格相等運算符

const missingObject = null;
const existingObject = { message: 'Hello!' };

missingObject  === null; // => true
existingObject === null; // => false

missingObject === null 的結果為 true,因為 missingObject 變數包含一個 null 值。如果變數包含非空值,比如對象,則表達式 existingObject === null 的結果為 false

2.1 null 是一個假值

nullfalse、0、"、undefinedNaN 都是假值。如果在條件語句中遇到它們,那麼 JavaScript 將把它們強製為 false

Boolean(null); // => false

if (null) {
  console.log('null is truthy');
} else {
  console.log('null is falsy'); // logs 'null is falsy'
}

2.2 typeof null

typeof value 類型操作符可以確定值的類型。例如,類型為 15 的是 numbertypeof { prop: 'Value' } 等於 object

有趣的是,null 值類型的結果是什麼

typeof null; // => 'object'

一個缺失的對象類型怎麼被判斷為 object? 原來 typoef null 作為 object 是早期 JavaScript 實現中的一個錯誤

不要使用 typeof 操作符檢測 null 值。如前所述,使用嚴格的相等運算符 myVar === null

如果你想使用 typeof 去檢查一個變數是否是一個對象,你必須排除掉 null 的情況

function isObject(object) {
  return typeof object === 'object' && object !== null;
}

isObject({ prop: 'Value' }); // => true
isObject(15);                // => false
isObject(null);              // => false

3. null 的陷阱

null 通常會在你希望使用對象的情況下意外出現。然後,如果嘗試從 null 中提取屬性,JavaScript 會拋出一個錯誤

讓我們再次使用 greetObject() 函數並嘗試從返回的對象中訪問 message 屬性

let who = '';

greetObject(who).message; 
// throws "TypeError: greetObject() is null"

因為 who 變數是一個空字元串,所以函數返回 null。當從 null 訪問 message 屬性時,將拋出類型錯誤錯誤

你可以通過使用 可選鏈操作符 來處理 null

let who = '';

greetObject(who)?.message ?? 'Hello, Stranger!';  
// => 'Hello, Stranger!'

或者使用下一節中描述的兩種選擇。

4. null 的替代方案

當你不能構造一個對象時,很容易返回 null。但這種做法也有缺點

一旦 null 出現在執行堆棧中,你總是必須檢查它

我們儘量避免返回 null

  • 返回預設對象而不是 null
  • 拋出錯誤而不是返回 null

讓我們回憶一下 greetObject() 函數返回 greeting 對象

當缺少參數時,可以返回一個預設對象,而不是返回 null

function greetObject(who) {
  if (!who) {
    who = 'Stranger';
  }
  return { message: `Hello, ${who}!` };
}

greetObject('Eric'); // => { message: 'Hello, Eric!' }
greetObject();       // => { message: 'Hello, Stranger!' }

或者拋出一個錯誤

function greetObject(who) {
  if (!who) {
    throw new Error('"who" argument is missing');
  }
  return { message: `Hello, ${who}!` };
}

greetObject('Eric'); // => { message: 'Hello, Eric!' }
greetObject();       // => throws an error

這些實踐可以讓你完全避免處理 null

5. null vs undefined

undefined 就是未初始化的變數或對象屬性的值

例如,如果在聲明變數時沒有賦初值,那麼訪問該變數的結果為 undefined

let myVariable;

myVariable; // => undefined

nullundefined 之間的主要區別是,null 表示丟失了的對象,而 undefined 表示未初始化的狀態

嚴格相等運算符 === 區分 nullundefined

null === undefined; // => false

而鬆散相等運算符 == 則認為 nullundefined 相等

null == undefined; // => true

我使用鬆散相等運算符檢查變數是否為 nullundefined

function isEmpty(value) {
  return value == null;
}

isEmpty(42);                // => false
isEmpty({ prop: 'Value' }); // => false
isEmpty(null);              // => true
isEmpty(undefined);         // => true

6. 總結

nullJavaScript 中的一個特殊值,表示丟失的對象

嚴格相等運算符判斷變數是否為空: variable === null

typoef 操作符用於確定變數的類型(number, string, boolean)。但是,typeofnull 情況下會引起誤解: typeof null 結果為 object

nullundefined 在某種程度上是等價的,但null 表示一個丟失的對象,而 undefined 表示未初始化狀態

儘可能避免返回 null 或將變數設置為 null。因為這種做法會導致 null 值的擴展和需要對 null 的驗證。相反,嘗試使用具有預設屬性的對象,或者甚至拋出錯誤會是更好的實踐

你會使用什麼方法來檢查 null?


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 不說那種建表的時候 設置好主鍵格式 的 解決方案. 事後諸葛啊. 誰都會不靠譜方案1 改主鍵表結構. 費時! 主鍵已經超長了.說明 數據量相當大. 改表結構的時間成本你能等得起嗎方案2 超長表 改表名作為歷史表 ,新建新表,然後根據業務情況將歷史表數據酌情複製到新表中. (比如最近3個月的數據. 不 ...
  • 摘要:《Index Checkpoints for Instant Recovery in In-Memory Database Systems》是由華為雲資料庫創新Lab一作發表在資料庫領域頂級會議VLDB'2022的學術論文。 本文分享自華為雲社區《VLDB'22 HiEngine極致RTO論文 ...
  • 編者按: Benchmarking 作為一個衡量標尺,可從不同的維度來客觀公正公平的評價相關產品,例如:對應數據測評而言,有 TPC-C、TPC-H,TP-DS 等等。現有的這些測評 TPC-X 標準(Benchmarking)真的適合現有的 OLTP&OLAP 混合型資料庫嗎?現在對於很多 HTA ...
  • 摘要:看GaussDB for Redis強擴展、高可用、強一致、高安全,如何玩轉各大游戲場景 本文分享自華為雲社區《GaussDB為什麼成為游戲行業的心頭愛?》,作者: GaussDB 資料庫 。 在結束忙碌工作回家的地鐵上,難得閑暇的周末下午,和朋友再來一局的入睡前......游戲已經成為了當下 ...
  • MySQL8 Group By 新特性 此生此夜不長好,明月明年何處看。 一、簡介 MySQL8 新特性之 Group By 不再隱式排序。MySQL8對於group by 欄位不再隱式排序,如需要排序,必須顯式加上 order by 子句。 二、MySQL5.7 Group By 數據準備 Sel ...
  • 本篇文章主要介紹 Redo Log 和 Undo Log: 1. 利用 Redo Log 和 Undo Log 實現本地事務的原子性、持久性 2. Redo Log 的寫回策略 3. Redo Log Buffer 的刷盤時機 ...
  • DDL:數據定義語言 註意:對錶操作的時候需要進入到對應的資料庫裡面去。 創建表:CREATE TABLE [IF NOT EXISTS] 'tbl_name' ( 欄位1 修飾符, col2 欄位2 修飾符, ...) 例如:創建一張名為stu1的表,表中包含的欄位有id,name和age,id的 ...
  • 酷暑終於過去,很多人伴著涼爽的秋風開啟了新一輪的健身計劃。當用戶進行戶外運動或使用跑步機、橢圓機等器械時,他們會希望在運動健康類App里點擊即可開啟運動並記錄運動數據。而對於開發者自己開發的應用來說,用戶在使用跟華為健康App綁定的運動設備運動時,可以直接在自己的App後臺控制用戶運動狀態並獲取實時 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...