<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [JS] 數據類型與特殊值的判斷方法

      由于JS是弱類型語言,判斷一個變量的數據類型是一個很常見的需求。

      下面介紹一些常用的判斷方法:

      typeof操作符

      typeof可以用來判斷除了null的基本數據類型和function,其它引用數據類型都會返回object。

      console.log(typeof "Hello"); // "string"
      console.log(typeof 42); // "number"
      console.log(typeof true); // "boolean"
      console.log(typeof undefined); // "undefined"
      console.log(typeof function(){}); // "function"
      
      console.log(typeof null); // "object" (這是一個歷史遺留的bug)
      console.log(typeof []); // "object"
      

      為什么typeof null會返回object ?

      在JS的最初版本中,使用32位二進制表示棧中的變量,二進制的前三位為類型標識tag,當前三位都是0時,表示object類型。但是null被設計為32位二進制都是0,因此會被錯誤地識別為object類型。

      由于這個錯誤影響范圍很大,后期并沒有被修復。

      ??harmony:typeof_null [ES Wiki] (archive.org)

      instanceof操作符

      語法:變量 instanceof 函數;

      返回值:布爾值,變量是否是指定的構造函數的實例,即變量的原型鏈上是否存在指定的構造函數

      特點:只用來判斷引用數據類型。

      console.log([] instanceof Array); // true
      console.log({} instanceof Object); // true
      console.log(function(){} instanceof Function); // true
      console.log(new Date() instanceof Date); // true
      

      對于基礎數據類型:

      1 instanceof Number ==> false
      
      let a = new Number(1);
      a instanceof Number ==> true
      

      注意instanceof在跨iframe或者不同的JavaScript執行環境時可能會失效,因為每個執行環境都有獨立的構造函數。

      Object.prototype.toString.call

      這是最通用和可靠的方法。通過Object.prototype.toString.call方法,可以精確地判斷變量的類型,不受執行環境的影響。

      console.log(Object.prototype.toString.call("Hello")); // "[object String]"
      console.log(Object.prototype.toString.call(42)); // "[object Number]"
      console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
      console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
      console.log(Object.prototype.toString.call(null)); // "[object Null]"
      console.log(Object.prototype.toString.call([])); // "[object Array]"
      console.log(Object.prototype.toString.call({})); // "[object Object]"
      console.log(Object.prototype.toString.call(function(){})); // "[object Function]"
      console.log(Object.prototype.toString.call(new Date())); // "[object Date]"
      

      isArray

      Array.isArray在ES5就存在了,與上述的Object.prototype.toString.call方法相比:

      • Array.isArray的兼容性沒有后者好,但是考慮到IE目前已經無了,基本可以放心使用;
      • Array.isArray作為原生的方法,底層實現會被引擎優化,通常比起后者的字符串比較操作性能會更好。

      判斷箭頭函數

      箭頭函數的特點:

      1. toString方法返回函數體會包含=>;(這個特點作為判斷標準不嚴謹,因為普通函數的函數體可能包含帶有=>字符的語句)
      2. 箭頭函數沒有prototype屬性,而普通函數有;
      3. 箭頭函數不能被當作構造函數,因此使用new關鍵字實例化會拋出異常。

      綜合判斷方法:

      function isArrowFunction(func) {
          if (typeof func !== 'function') {
              return false;
          }
          try {
              new func();
              return false;
          } catch (e) {
              return !func.hasOwnProperty('prototype') && func.toString().includes('=>');
          }
      }
      

      判斷async函數

      async函數的特點:

      1. toString方法返回的字符串帶有async(開頭位置);
      2. Object.prototype.toString.call會返回[object AsyncFunction];
      3. AsyncFunction構造函數的實例。(由于在大多數環境中,AsyncFunction無法直接訪問,可以通過構建一個新的async函數來獲得這個構造函數)。

      綜合判斷方法:

      function isAsyncFunction(func) {
          if (typeof func !== 'function') {
              return false;
          }
          const AsyncFunction = (async function() {}).constructor;
          return func instanceof AsyncFunction || 
                 Object.prototype.toString.call(func) === '[object AsyncFunction]' || 
                 func.toString().trim().startsWith('async');
      }
      

      判斷class

      常見方法:

      1. 使用 typeofFunction.prototype.toString:通過 typeof 檢查是否是函數,然后通過 toString 檢查字符串表示形式中是否包含 class 關鍵字;
      2. 檢查原型鏈:類的原型鏈上通常會有 constructor 屬性,并且這個 constructor 屬性指向類自身;
      3. 使用new檢查:類不能在沒有 new 關鍵字的情況下調用,而函數可以。

      綜合方法:

      function isClass(func) {
          if (typeof func !== 'function') {
              return false;
          }
          try {
              func();
              return false;
          } catch (e) {
              if (e.message.includes('Class constructor') || e.message.includes('class constructors')) {
                  return true;
              }
              return /^class\s/.test(Function.prototype.toString.call(func));
          }
      }
      

      示例文件

      // is.js
      
      /**
       * 判斷是否為字符串
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isString(value) {
          return Object.prototype.toString.call(value) === '[object String]';
      }
      
      /**
       * 判斷是否為數字
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isNumber(value) {
          return Object.prototype.toString.call(value) === '[object Number]';
      }
      
      /**
       * 判斷是否為布爾值
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isBoolean(value) {
          return Object.prototype.toString.call(value) === '[object Boolean]';
      }
      
      /**
       * 判斷是否為 undefined
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isUndefined(value) {
          return Object.prototype.toString.call(value) === '[object Undefined]';
      }
      
      /**
       * 判斷是否為 null
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isNull(value) {
          return Object.prototype.toString.call(value) === '[object Null]';
      }
      
      /**
       * 判斷是否為數組
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isArray(value) {
          return Array.isArray(value);
          // return Object.prototype.toString.call(value) === '[object Array]';
      }
      
      /**
       * 判斷是否為對象
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isObject(value) {
          return Object.prototype.toString.call(value) === '[object Object]';
      }
      
      /**
       * 判斷是否為函數
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isFunction(value) {
          return Object.prototype.toString.call(value) === '[object Function]';
      }
      
      /**
       * 判斷是否為日期
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isDate(value) {
          return Object.prototype.toString.call(value) === '[object Date]';
      }
      
      /**
       * 判斷是否為正則表達式
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isRegExp(value) {
          return Object.prototype.toString.call(value) === '[object RegExp]';
      }
      
      /**
       * 判斷是否為錯誤對象
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isError(value) {
          return Object.prototype.toString.call(value) === '[object Error]';
      }
      
      /**
       * 判斷是否為 Symbol
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isSymbol(value) {
          return Object.prototype.toString.call(value) === '[object Symbol]';
      }
      
      /**
       * 判斷是否為 Promise
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isPromise(value) {
          return Object.prototype.toString.call(value) === '[object Promise]';
      }
      
      /**
       * 判斷是否為 Set
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isSet(value) {
          return Object.prototype.toString.call(value) === '[object Set]';
      }
      
      /**
       * 判斷是否為 Map
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isMap(value) {
          return Object.prototype.toString.call(value) === '[object Map]';
      }
      
      /**
       * 判斷是否為 箭頭函數
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isArrowFunction(func) {
          if (typeof func !== 'function') {
              return false;
          }
          try {
              new func();
              return false;
          } catch (e) {
              return !func.hasOwnProperty('prototype') && func.toString().includes('=>');
          }
      }
      
      /**
       * 判斷是否為 async函數
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isAsyncFunction(func) {
          if (typeof func !== 'function') {
              return false;
          }
          const AsyncFunction = (async function() {}).constructor;
          return func instanceof AsyncFunction || 
                 Object.prototype.toString.call(func) === '[object AsyncFunction]' || 
                 func.toString().trim().startsWith('async');
      }
      
      /**
       * 判斷是否為 class
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isClass(func) {
          if (typeof func !== 'function') {
              return false;
          }
          try {
              func();
              return false;
          } catch (e) {
              if (e.message.includes('Class constructor') || e.message.includes('class constructors')) {
                  return true;
              }
              return /^class\s/.test(Function.prototype.toString.call(func));
          }
      }
      
      /**
       * 判斷是否為 空對象
       * @param value - 需要判斷的值
       * @returns boolean
       */
      function isEmptyObject(value) {
          return isObject(value) && Object.keys(value).length === 0;
      }
      
      // 導出函數
      module.exports = {
          // type
          isString,
          isNumber,
          isBoolean,
          isUndefined,
          isNull,
          isArray,
          isObject,
          isFunction,
          isDate,
          isRegExp,
          isError,
          isSymbol,
          isPromise,
          isSet,
          isMap,
          isArrowFunction,
          isAsyncFunction,
          isClass,
          // value
          isEmptyObject,
      };
      
      

      值比較

      除了類型比較,JS里有一些值也是經常需要判斷的。

      NaN、Infinitity、Integer、safeInteger

      這些和數值相關的判斷都在Number的靜態方法里了。

      Number.isNaN(value); // 是否NaN
      Number.isFinite(value); // 是否有限數值
      
      function isInfinitiy(value){ // 是否是無窮大
          return !Number.isFinite(value);
      	// 另一種寫法
          return value === Infinity || value === -Infinity;
      }
      
      Number.isInteger(value); // 判斷整數
      Number.isSafeInteger(value); // 判斷安全整數
      
      

      判斷空對象

      空對象指的是不包含任何可枚舉屬性的對象。

      function isEmptyObject(value) {
          return isObject(value) && Object.keys(value).length === 0;
      }
      
      function isObject(value) {
          return Object.prototype.toString.call(value) === '[object Object]';
      }
      
      posted @ 2024-06-30 22:36  feixianxing  閱讀(144)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 男女爽爽无遮挡午夜视频| 日韩人妻无码一区二区三区久久| 午夜精品久久久久久| 无码人妻久久一区二区三区app| 青青在线视频一区二区三区| 五月天天天综合精品无码| 亚洲中文字幕人成影院| 国产一区二区三区导航| 亚洲精品入口一区二区乱| 又爆又大又粗又硬又黄的a片| 激情五月日韩中文字幕| 国产中文字幕在线一区| 亚洲av成人一区二区三区| 在线天堂最新版资源| 亚洲成人高清av在线| 东京热大乱系列无码| 国产欧美精品一区二区三区-老狼 真实单亲乱l仑对白视频 | 国产SM重味一区二区三区| 亚洲综合一区二区三区不卡| 国产成人无码区免费内射一片色欲| 亚洲男人的天堂网站| 精品国精品自拍自在线| 小污女小欲女导航| 久草热大美女黄色片免费看 | 91麻豆视频国产一区二区| 一本色道久久88亚洲精品综合 | 久久久久青草线蕉综合超碰| 人妻系列无码专区免费| 肉大捧一进一出免费视频| 国外av片免费看一区二区三区| 亚洲熟妇在线视频观看| 精品久久久久中文字幕日本| 国产精品亚洲一区二区三区| 2020国产欧洲精品网站| 最新中文字幕国产精品| 人人爽人人爽人人爽| 国产老熟女视频一区二区| 福利一区二区1000| 南木林县| 欧美精欧美乱码一二三四区 | 无码人妻丝袜在线视频|