在 JS 中檢查變量是否爲數組的多種方式,並說說 ES6 引入檢查數組的緣起!

做者:Samantha Ming
譯者:前端小智
來源:medium
點贊再看,微信搜索 【大遷世界】 關注這個沒有大廠背景,但有着一股向上積極心態人。本文 GitHub https://github.com/qq44924588... 上已經收錄,文章的已分類,也整理了不少個人文檔,和教程資料。

下面的代碼片斷用於檢查變量或值是否爲數組。 在主流的瀏覽器可使用Array.isArray方法。 對於較舊的瀏覽器,可使用polyfill👍前端

const variable = ['🍝', '🍜', '🍲'];

// 主流瀏覽器
Array.isArray(variable);

// 老式瀏覽器
Object.prototype.toString.call(variable) === '[object Array]';

檢查數組的現代方法

檢查數組的最佳方法是使用內置的Array.isArray()👏git

Array.isArray([]); // true
Array.isArray(['🍝']); // true
Array.isArray(new Array('🍝')); // true

瀏覽器支持

瀏覽器對 Array.isArray()的支持很是好 👍github

clipboard.png

適用於舊版瀏覽器的 Polyfill

若是須要讓較早的瀏覽器支持,則可使用此MDN polyfillwindows

if (!Array.isArray) {
  Array.isArray = function(org) {
    return Object.prototype.toString.call(org) === '[object Array]'
  }
}

其它方式:使用 Lodash 或 Underscore

若是你使用的是外部庫,它們也有一些內置方法👏數組

Lodash

檢查值是否爲數組對象。
const array = ['🍝', '🍜', '🍲'];
const notArray = 'not array';

_.isArray(array); // true
_.isArray(notArray); // false

Underscore

若是對象是數組,返回 true。
const array = ['🍝', '🍜', '🍲'];
const notArray = 'not array';

_.isArray(array); // true
_.isArray(notArray); // false

爲何咱們不能使用typeof?

一般,咱們要檢查值的類型,咱們只需使用 typeof瀏覽器

typeof 'string'; // 'string'
typeof 100; // 'number'
typeof true; // 'boolean'
typeof false; // 'boolean'
typeof function() {}; // 'function'
typeof {}; // 'object'

typeof []; // 'object' <-- 😱

問題是數組實際上處於 Object 數據類型的保護傘之下。因此typeof 返回值是沒問題。不幸的是,這對咱們並無什麼幫助,由於咱們只想檢查值是否是數組。微信

typeof

Type 例子 返回值
String typeof "hello" "string"
Boolean typeof true
typeof false
"boolean"
Number typeof 100 "number"
Undefined typeof undefined "undefined"
Function typeof function() {} "function"
Null typeof null "object"
非基本類型 typeof {}
typeof []
"object"

基本類型

在 JS 中有 6 種基本數據類型數據結構

  1. string
  2. number
  3. bigint
  4. boolean
  5. undefined
  6. symbol

非基本類型 (對象)

對象是指包含數據和使用數據的指令的數據結構。它們是經過引用存儲的

我比較喜歡稱它爲「非基本類型 」,但它們被稱爲Objectapp

  1. object
  2. array
  3. function

儘管當咱們在函數上使用typeof來檢查函數的類型,它返回「 function」,但實際上它是一個對象。框架

》 MDN:儘管每一個 Function 構造函數都是從 Object 構造函數派生的,但它是Function的特殊簡寫形式。

代碼診斷 👩‍🔬

我收到了不少開發都提供用來檢查Array的不一樣解決方案。 乍一看,它們彷佛是不錯的解決方案。 有點遺憾的是,有些問題或極端狀況使它們不理想。

Array.length 的問題

const array = ['🍝', '🍜', '🍲'];

array.length; // 3

😷 若是數組有長度,咱們能夠假設它是數組?

👩‍⚕️ 遺憾的是,此解決方案的問題在於還有其餘具備長度即即的數據類型,如:字符串。 所以,這可能致使誤報。

const string = 'not array';

string.length; // 9

即便一個對象也能夠有length屬性:

const object = { length: 2 };
const array = ['🍝', '🍜', '🍲'];

typeof array === 'object' && Boolean(array.length); // true
typeof object === 'object' && Boolean(object.length); // true <-- 😱

instanceof 的問題

const array = ['🍝', '🍜', '🍲'];

array instanceof Array; // true

這種方法在 ES5 很常見, 在許多狀況下,這種能夠很好的工做。 可是,這有一個陷阱! 它不適用於多個上下文(例如 框架 或windows)。 由於每一個框架在其本身的執行環境中都有不一樣的做用域。 所以,它具備不一樣的全局對象和不一樣的構造函數。 所以,若是嘗試針對該框架的上下文測試數組,則該數組不會返回true,而會錯誤地返回false。

window.frames: frames[] 是窗口中全部命名的框架組成的數組。這個數組的每一個元素都是一個Window對象,對應於窗口中的一個框架。
const frameNode = document.createElement('iframe'); // 建立一個iframe元素節點
document.body.appendChild(frameNode);
// 從咱們當前的窗口訪問框架
const frameBrowser = window.frames[window.frames.length - 1];
// 訪問咱們建立的框架的「數組」對象
frameArray = frameBrowser.Array; 

// 在咱們的框架環境中建立一個新的數組
const newFrameArray = new frameArray('🍝', '🍜', '🍲');

newFrameArray instanceof Array; // ❌ false

Array.isArray(newFrameArray); // ✅ true

構造函數的問題

const array = ['🍝', '🍜', '🍲'];

array.constructor === Array; // true

這是另外一個很好的解決方案。不幸的是,這和instanceof有一樣的問題。它也不能在多個上下文中工做。

// ...

newFrameArray.constructor === Array; // ❌ false

Array.isArray(newFrameArray); // ✅ true

原文:https://www.samanthaming.com/...

編輯中可能存在的bug無法實時知道,過後爲了解決這些bug,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

交流

文章每週持續更新,能夠微信搜索 【大遷世界 】 第一時間閱讀,回覆 【福利】 有多份前端視頻等着你,本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,歡迎Star。

相關文章
相關標籤/搜索