中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript類型如何判斷

發布時間:2022-05-26 09:13:55 來源:億速云 閱讀:134 作者:zzz 欄目:開發技術

這篇“JavaScript類型如何判斷”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“JavaScript類型如何判斷”文章吧。

    一、JavaScript 基本類型

    首先介紹一下JavaScript中的八大基本類型

    1、原始數據類型

    除對象類型(object)以外的其它任何類型定義的不可變的值(值本身無法被改變)。例如(與 C 語言不同),JavaScript 中字符串是不可變的(譯注:如,JavaScript 中對字符串的操作一定返回了一個新字符串,原始字符串并沒有被改變)。我們稱這些類型的值為“原始值”。 —— MDN

    (1)布爾類型(Boolean)

    布爾表示一個邏輯實體,可以有兩個值:truefalse 、

    (2)Null類型

    • Null 類型只有一個值:null

    • 值 null 是一個字面量,是表示缺少的標識,只是變量未指向任何對象。

    • 注意:可以把 null 作為尚未創建的對象,但是 null 并非對象。

    (3)Undefined類型

    • undefined:一個聲明未定義的變量的初始值,或沒有實際參數的形式參數。

    • undefined全局對象的一個屬性。也就是說,它是全局作用域的一個變量。undefined的最初值就是原始數據類型undefined。

    console.log(undefined in window)  //  true
    let a;
    console.log(a)  // undefined
    • 一個函數如果沒有使用return語句指定返回值,就會返回一個undefined值。

    function f() {
    }
    console.log(f())  // undefined

    (4)數字類型(Number)

    • 數字類型是一種基于 IEEE 754 標準的雙精度 64 位二進制格式的值,能表示整數和浮點值

    • 值的范圍: Number.MIN_VALUE(5e-324)— Number.MAX_VALUE(1.7976931348623157e+308)

    • 如果某個正值大于 Number.MAX_VALUE,則表示為Infinity(或者+Infinity)

      • 如果某個負值小于 -Number.MAX_VALUE則表示為-Infinity

      • 如果某個正值小于 Number.MIN_VALUE,則表示為0(或者+0)

      • 如果某個負值大于 -Number.MIN_VALUE則表示為-0

    // 注意:Number.MIN_VALUE(5e-324)— Number.MAX_VALUE(1.7976931348623157e+308) 是可以表示的正值范圍
    console.log(Number.MIN_VALUE);  // 5e-324
    console.log(Number.MAX_VALUE);  // 1.7976931348623157e+308
    
    console.log(1e310);  // Infinity
    console.log(-1e310);  // -Infinity
    
    console.log(1e-330);  // 0
    console.log(-1e-330);  // 0
    • NaN(非數值,Not-a-Number)。

    not-a-number:NaN 是一個全局對象的屬性。NaN 屬性的初始值就是 NaN,和 Number.NaN 的值一樣。

    • 數字類型中只有一個整數有兩種表示方法:0可表示為-0和+0(0是+0的簡寫)。

    (5)BigInt

    • BigInt 類型是 JavaScript 中的一個基礎的數值類型,可以表示任意精度的整數。使用 BigInt,您可以安全地存儲和操作大整數,甚至可以超過數字類型安全整數限制。(BigInt 與 Number 的主要區別在于,BigInt能在內存中精確表示超過安全限制的整數)

    // 數字類型安全整數限制
    console.log(Number.MIN_SAFE_INTEGER)  // -9007199254740991
    console.log(Number.MAX_SAFE_INTEGER)  // 9007199254740991
    • BigInt 是通過在整數末尾附加字母n或調用構造函數來創建的。

    // 構造函數創建
    // BigInt() 不與 new 運算符一起使用。
    let a = BigInt(1);
    // 末尾附加字母n創建
    let b = 1n;
    console.log(a)  // 1n
    console.log(b)  // 2n
    • BigInt不能與數字相互運算。否則,將拋出TypeError

    console.log(1 + 1n);
    //Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

    (6)字符串類型(String)

    JavaScript 的字符串類型用于表示文本數據。它是一組 16 位的無符號整數值的“元素”。在字符串中的每個元素占據了字符串的位置。第一個元素的索引為0,下一個是索引1,依此類推。字符串的長度是它的元素的數量。

    (7)符號類型(Symbols)

    • 符號(Symbols)類型是唯一不可修改的原始值,該類型的性質在于這個類型的值可以用來創建匿名的對象屬性,可以用來作為對象的鍵(key)

    • 可以通過調用函數 Symbol() 來創建 Symbol 數據類型實例。

    • 當一個 symbol 類型的值在屬性賦值語句中被用作標識符,該屬性(像這個 symbol 一樣)是匿名的;并且是不可枚舉的。因為這個屬性是不可枚舉的,它不會在循環結構 “for( ... in ...)” 中作為成員出現,也因為這個屬性是匿名的,它同樣不會出現在 “Object.getOwnPropertyNames()” 的返回數組里。這個屬性可以通過創建時的原始 symbol 值訪問到,或者通過遍歷 “Object.getOwnPropertySymbols() ” 返回的數組。在之前的代碼示例中,通過保存在變量 myPrivateMethod的值可以訪問到對象屬性。

    • symbol 值提供了一種自定義類可以創建私有成員的方式,并維護一個僅適用于該類的 symbol 注冊表。 自定義類可以使用 symbol 值來創建“自有”屬性,這些屬性避免了不必要的被偶然發現帶來的影響。 在類定義中,動態創建的 symbol 值將保存到作用域變量中,該變量只能在類定義中私有地使用。

    2、引用數據類型

    對象類型(Object)

    在計算機科學中, 對象(object)是指內存中的可以被標識符引用的一塊區域。

    在 JavaScript 中,對象可以被看作是一組屬性的集合。用對象字面量語法來定義一個對象時,會自動初始化一組屬性。而后,這些屬性還可以被添加和移除。

    • 屬性的值可以是任意類型,包括其它對象。

    • 屬性使用鍵(key)來標識,它的鍵值可以是一個字符串或者符號值(Symbol)。

    對象擁有兩種屬性:

    a、數據屬性

    JavaScript類型如何判斷

    b、訪問器屬性

    JavaScript類型如何判斷

    JavaScript中提供了很多內置對象,可參考MDN官方文檔。

    3、兩種數據類型的存儲方式

    (1)原始數據類型

    基礎類型存儲在棧內存,被引用或拷貝時,會創建一個完全相等的變量;占據空間小、大小固定,屬于被頻繁使用數據,所以放入棧中存儲。

    (2)引用數據類型

    引用類型存儲在堆內存,存儲的是地址,多個引用指向同一個地址,這里會涉及一個“共享”的概念;占據空間大、大小不固定。引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址后從堆中獲得實體。

    所以,在 JavaScript 中,原始類型的賦值會完整復制變量值,而引用類型的賦值是復制引用地址。

    二、Javascript 數據類型判斷的幾種方法

    1、typeof

    typeof操作符返回一個字符串,表示未經計算的操作數的類型。

    語法:

    // operand:一個表示對象或原始值的表達式,其類型將被返回
    typeof operand
    typeof(operand)

    返回值:

    "undefined" "object"  "boolean"  "number" "bigint" "string" "symbol" "function" "object"

    (1)不同數據類型的 typeof 值

    // 歷史遺留問題
    console.log(typeof null);  // object
    // Undefined 類型typeof值為 undefined
    console.log(typeof undefined);  // undefined
    // 未定義的變量 typeof值也為 undefined
    console.log(typeof a);  // undefined
    // 非數值
    console.log(typeof NaN);  // number
    // 無窮大
    console.log(typeof Infinity);  // number
    // 除 Null 和 Undefined 之外的原始數據類型 typeof 值都是對應的類型
    console.log(typeof true);  // boolean
    console.log(typeof 2);  // number
    console.log(typeof 2n);  // bigint
    console.log(typeof BigInt(1));  // bigint
    console.log(typeof 'str');  // string
    console.log(typeof Symbol(1));  // symbol
    console.log(typeof Boolean(true));  // boolean
    console.log(typeof Number(1));  // number
    console.log(typeof String('str'));  // string
    // 基本包裝類型
    console.log(typeof new Boolean(true));  // object
    console.log(typeof new Number(1));  // object
    console.log(typeof new String('str'));  // object
    // 字面量
    console.log(typeof {});  // object
    console.log(typeof []);  // object
    console.log(typeof /1/);  // object
    // 除了 Function 對象實例, typeof值都是 object
    console.log(typeof new Object());  // object
    console.log(typeof new Array());  // object
    console.log(typeof new Map());  // object
    console.log(typeof new Set());  // object
    console.log(typeof new Date());  // object
    console.log(typeof new RegExp());  // object
    console.log(typeof Math);  // object
    // Function 對象實例, typeof值為 function
    console.log(typeof new Function());  // function
    console.log(typeof Function);  // function
    console.log(typeof Array);  // function
    console.log(typeof Set);  // function
    console.log(typeof Date);  // function
    console.log(typeof RegExp);  // function
    console.log(typeof Object);  // function

    (2) typeof null === 'object' 的原因

    “typeof null”錯誤是 JavaScript 第一版的遺留物。在這個版本中,值存儲在 32 位單元中,由一個小型標簽(1-3 位)和值的實際數據組成。類型標簽存儲在單元的低位中。

    其中有五個:

    • 000:對象。數據是對對象的引用。

    • 1:整數。數據是一個 31 位有符號整數。

    • 010:雙倍。數據是對雙浮點數的引用。

    • 100:字符串。數據是對字符串的引用。

    • 110:布爾值。數據是布爾值。

    也就是說,最低位是任一位,那么類型標簽只有一位長。或者為零,則類型標簽的長度為三位,為四種類型提供兩個額外的位。

    有兩個值是特殊的:

    • undefined ( JSVAL_VOID ) 是整數 -2 30(整數范圍之外的數字)。

    • null ( JSVAL_NULL ) 是機器碼 NULL 指針。或者:一個對象類型標簽加上一個為零的引用。(表示為全0)

    所以 typeof 認為 null 是一個 object

    (3)對象類型 typeof 返回值的理解

    針對對象類型,個人理解 的是:

    • 如果是Function對象, 那么返回值則是function

    • 如果是其他任何普通對象, 那么返回值則是object,

    (4)關于 typeof Boolean(true) 和 typeof new Boolean(true)不同的原因

    // 簡單調用Boolean() 函數
    console.log(Boolean(true));  // true
    // 創建一個Boolean對象
    console.log(new Boolean(true));  // Boolean {true}

    Boolean(true) 的返回值就是Boolean類型的數據,newBoolean(true)返回的是一個Boolean對象。

    (5)總結

    • typeof 可以判斷除 null 之外所有原始數據類型

    • typeof 在判斷實例類型時,根據實例的構造函數返回 object 或 function

    • typeof null === 'object' 是一個歷史遺留問題,無法修改。

    • typeof NaN === 'number'

    2、instanceof

    instanceof運算符用于檢測構造函數的 prototype 屬性是否出現在某個實例對象的原型鏈

    語法:

    // object:某個實例對象
    // constructor:某個構造函數
    object instanceof constructor

    (1)相關例子

    // instanceof 右邊是一個構造函數,所以undefined 和 null 不能使用instanceof,下面兩條語句執行會報錯
    // console.log(undefined instanceof Undefined);
    // console.log(null instanceof Null);
    // 對于原始數據類型無法檢測
    console.log(2 instanceof Number);  // false
    console.log(1n instanceof BigInt);  // false
    console.log(true instanceof Boolean);  // false 
    console.log('str' instanceof String);  // false  
    console.log(Symbol(1) instanceof Symbol);  // false
    
    // 可以檢測內置對象類型
    console.log([] instanceof Array);  // true
    console.log(function(){} instanceof Function);  // true
    console.log({} instanceof Object);  // true   
    console.log(/1/ instanceof RegExp);  // true 
    // 所有函數對象實例原型鏈上都存在Function
    console.log(Array instanceof Function);  // true 
    console.log(Set instanceof Function);  // true 
    console.log(Map instanceof Function);  // true 
    console.log(Date instanceof Function);  // true 
    console.log(RegExp instanceof Function);  // true 
    console.log(Function instanceof Function);  // true 
    console.log(Object instanceof Function);  // true 
    // Object 是所有實例對象原型鏈的盡頭
    console.log(Array instanceof Object);  // true 
    console.log(Set instanceof Object);  // true 
    console.log(Map instanceof Object);  // true 
    console.log(Date instanceof Object);  // true 
    console.log(RegExp instanceof Object);  // true 
    console.log(Function instanceof Object);  // true 
    console.log(Object instanceof Object);  // true 
    function foo() {}
    // foo 是 Function的一個實例
    console.log(foo instanceof Object);  // true
    console.log(foo instanceof Function);  // true
    // new foo() 是 foo 的一個實例
    console.log(new foo() instanceof foo);  // true
    console.log(new foo() instanceof Object);  // true
    console.log(new foo() instanceof Function);  // false
    // foo() 返回的是undefined
    console.log(foo() instanceof Object);  // false
    console.log(foo() instanceof Function);  // false

    (2) 當構造函數的proptotype發生改變時,instanceof 結果可能會出錯

    function foo() {}
    let f = new foo();
    console.log(f instanceof foo)  // true
    // foo 原型發生改變
    foo.prototype = Array.prototype;
    console.log(f instanceof foo);  // false

    (3)手動實現 instanceof

    function myInstanceof(left, right) {
        // 獲得構造函數的原型
        let prototype = right.prototype
        // 獲得對象的原型
        left = left.__proto__
        // 判斷對象的類型是否等于類型的原型
        while (true) {
            // 原型鏈的盡頭是 null,說明實例對象的原型鏈遍歷結束
        	if (left === null)
        		return false
        	if (prototype === left)
        		return true
        	left = left.__proto__
        }
    }

    上述手動實現只是實現了基本功能,但與原生instanceof仍然存在差別,例如:

    • 未對 right 進行錯誤處理

    // 檢驗right 是否是一個對象(Object)
    if (right is not Object){
        throw new TypeError(" Uncaught TypeError: Right-hand side of 'instanceof' is not Object")
    }
    // 檢驗 right 是否可被調用
    if (right is not callable) {
        throw new TypeError(" Uncaught TypeError: Right-hand side of 'instanceof' is not callable")
    }
    • myInstanceof('str', String) === true

    console.log(_instanceof('str', String))  // true

    有關instanceof 原理,可繼續深入了解原型鏈相關知識點。

    (4)總結

    • instanceof 不能判斷原始數據類型

    • instanceof 能夠判斷引用數據類型,但由于是查找原型鏈,所以不能很精準指出數據類型。

    例如:

    console.log([] instanceof Array);  // true
    console.log([] instanceof Object);  // true
    • 當構造函數的 prototype 發生改變時,會導致 instanceof 結果發生改變,詳見(2)

    所以 instanceof 用于判斷數據類型也存在弊端。

    3、構造函數(constructor)

    (1)相關例子

    // null 和 undefined 沒有構造函數
    onsole.log(null.constructor)  // TypeError
    onsole.log(undefined.constructor) // TypeError
    // 原始數據類型
    console.log((2).constructor === Number); // true
    console.log((2n).constructor === BigInt); // true
    console.log((true).constructor === Boolean); // true
    console.log(('str').constructor === String); // true
    console.log(Symbol(1).constructor === Symbol); // true
    // 字面量
    console.log(([]).constructor === Array); // true
    console.log((/1/).constructor === RegExp); // true
    console.log((function() {}).constructor === Function); // true
    console.log(({}).constructor === Object); // true
    // JavaScript中的內置函數對象的構造函數為 Function
    console.log(Array.constructor === Function); // true
    console.log(String.constructor === Function); // true
    console.log(Function.constructor === Function); // true
    console.log(Object.constructor === Function); // true
    // JavaScript中的內置普通對象的構造函數為 Object
    console.log(Math.constructor === Object); // true
    console.log(JSON.constructor === Object); // true
    console.log(Atomics.constructor === Object); // true
    console.log(Intl.constructor === Object); // true
    console.log(Reflect.constructor === Object); // true
    console.log(WebAssembly.constructor === Object); // true

    (2)如果創建一個對象前修改構造函數的原型,會導致constructor不可靠

    function Fn(){};
    Fn.prototype=new Array();
    var f=new Fn();
    console.log(f.constructor===Fn);    // false
    console.log(f.constructor===Array); // true

    (3)總結

    • 通過構造函數 constructor 能夠準確判斷出數據類型,但 null 和 undefined 沒有構造函數,無法判斷

    • 內置函數對象的構造函數都是 Function,例如 Array、Map等;內置普通對象的構造函數是Object,例如:JSON、Atomic、Intl、Reflect、WebAssembly 等

    • 在創建實例前修改實例的原型,會導致constructor不可靠

    所以 constructor 判斷數據類型也存在弊端。

    4、Object.prototype.toString.call()

    (1)Object.prototype.toString()

    每個對象都有一個toString()方法,當該對象被表示為一個文本值時,或者一個對象以預期的字符串方式引用時自動調用。默認情況下,toString()方法被每個Object對象繼承。如果此方法在自定義對象中未被覆蓋,toString() 返回  "[object type]" ,其中type是對象的類型 —— MDN

    (2) Object.prototype.toString.call() 實例

    // 原始數據類型
    console.log(Object.prototype.toString.call(undefined))  // [object Undefined]
    console.log(Object.prototype.toString.call(null))  // [object Null]
    console.log(Object.prototype.toString.call(1))  // [object Number]
    console.log(Object.prototype.toString.call(1n))  // [object BigInt]
    console.log(Object.prototype.toString.call(true))  // [object Boolean]
    console.log(Object.prototype.toString.call('str'))  // [object String]
    console.log(Object.prototype.toString.call(Symbol(1)))  // [object Symbol]
    // 字面量
    console.log(Object.prototype.toString.call({}))  // [object object]
    console.log(Object.prototype.toString.call([]))  // [object Array]
    console.log(Object.prototype.toString.call(/1/))  // [object RegExp]
    console.log(Object.prototype.toString.call(NaN))  // [object Number]
    console.log(Object.prototype.toString.call(Infinity))  // [object Number]
    console.log(Object.prototype.toString.call(globalThis))  // [object Window]
    // 內置函數對象實例
    console.log(Object.prototype.toString.call(new Array()))  // [object Array]
    console.log(Object.prototype.toString.call(new Map()))  // [object Map]
    console.log(Object.prototype.toString.call(new Set()))  // [object Set]
    console.log(Object.prototype.toString.call(new Date()))  // [object Date]
    console.log(Object.prototype.toString.call(new Function()))  // [object Function]
    // 內置普通對象本身
    console.log(Object.prototype.toString.call(Math))  // [object Math]
    console.log(Object.prototype.toString.call(JSON))  // [object JSON]
    console.log(Object.prototype.toString.call(Reflect))  // [object Reflect]
    // 內置函數對象本身
    console.log(Object.prototype.toString.call(Array))  // [object Function]
    console.log(Object.prototype.toString.call(Map))  // [object Function]
    console.log(Object.prototype.toString.call(Function))  // [object Function]
    console.log(Object.prototype.toString.call(Object))  // [object Function]
    // 瀏覽器全局對象
    console.log(Object.prototype.toString.call(document))  // [object HTMLDocument]
    console.log(Object.prototype.toString.call(window))  // [object Window]
    // 自定義構造函數
    function Foo() {}
    f = new Foo();
    console.log(Object.prototype.toString.call(f))  // [object object]
    console.log(Object.prototype.toString.call(Foo))  // [object Function]

    (3)基于Object.prototype.toString.call()實現數據類型判斷

    function getType(obj){
      let type  = typeof obj;
      if (type !== "object") {    // 先進行typeof判斷,如果是基礎數據類型,直接返回
        return type;
      }
      // 對于typeof返回結果是object的,再進行如下的判斷,正則返回結果
      return Object.prototype.toString.call(obj).replace(/^[object (\S+)]$/, '$1');  // 注意正則中間有個空格
    }

    (4)總結

    Object.prototype.toString.call() 能準確判斷數據類型。

    三、寫在最后

    • 除了 Null 之外的原始數據類型,均可使用 typeof 判斷數據類型。

    • Object.prototype.toString.call()  是判斷數據類型的最好的方法。

    • 有關 instanceof 和 constructor , 可以深入去了解JavaScript中的原型鏈。

    以上就是關于“JavaScript類型如何判斷”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    岐山县| 涞源县| 重庆市| 静海县| 蓬溪县| 灵寿县| 内丘县| 白城市| 湖北省| 洱源县| 清水县| 鄂托克前旗| 沙雅县| 留坝县| 清丰县| 桐庐县| 固始县| 潢川县| 东辽县| 嵊州市| 于田县| 黄冈市| 平顺县| 南丹县| 五家渠市| 青浦区| 渝中区| 栖霞市| 三原县| 迁西县| 葫芦岛市| 上蔡县| 桐梓县| 滦平县| 开封市| 沁源县| 遂昌县| 东明县| 哈尔滨市| 福建省| 台南市|