摘要:可用于判斷多種數據類型基本數據類型和內置對象,然而對于一些自定義構造函數生成的對象就不能進行判斷了。判斷是不是所有數據類型中,只有不等于它本身判斷數組的方法除了上文提到的三種方法可判斷外,還有一個構造函數自帶的方法可判斷。
數據類型的分類
要想判斷數據類型,首先要知道數據類型的分類。數據類型分為基本數據類型和引用數據類型。
基本數據類型基本數據類型有 五 種,ES6中新加了第 六 種基本數據類型——Symbol 類型。
數值 (number): 整數和小數。
字符串 (string): 文本
布爾值 (boolean):true 和 false 。
undefined: 表示‘未定義’或不存在。一般情況下變量在聲明后未賦值前都是undefined。
null: 空值。
symbol: ES6 引入的新原始數據類型,表示獨一無二的值。
引用數據類型引用類型數據也會統稱為對象,即廣義的對象,通常除了基本數據類型的其它數據都屬于引用類型數據。
對象 (object): 狹義的對象,{key1:value1, key2:value2,...}
數組 (array): [value1,value2,...]
函數 (function)
日期 (date)
正則表達式 (RegExp)
......
數據類型綜合判斷的各種方法 typeof 運算符typeof 返回字符串,number、string、boolean、symbol、undefined、function,所有其它的引用類型數據都返回 object,null 也返回 object。
typeof 666 // "number" typeof "dora" // "string" typeof true // "boolean" typeof Symbol() // "symbol" typeof undefined // "undefined" typeof null // "object" typeof function(){} // "function" typeof [] // "object" typeof /dora/ // "object"優點
可利用判斷 undefined 來檢查一個沒有聲明的變量,而不報錯。實際編程中,這個特點通常用在判斷語句中。
// 錯誤的寫法 if (v) { // ... } // ReferenceError: v is not defined // 正確的寫法 if (typeof v === "undefined") { // 這種寫法在 v 沒有聲明的時候不會報錯。 }
注意
ES6中引入了 let 之后,這個方法也不是萬能的了。當變量在代碼塊內用 let 聲明的時候,會形成“暫時性死區”(temporal dead zone,簡稱 TDZ),此時這個方法就沒用了,typeof 還是會報錯。
typeof x; // ReferenceError let x;缺點
不能準確的判斷引用類型數據的具體類型,除了函數外,其余的都是返回object。
typeof {} // "object" typeof [] // "object"
此時,在需要判斷數組或者對象時,就不適用了。
Object.prototype.toString.call(value)Object.prototype.toString() 方法返回對象的類型字符串,因此可以用來判斷一個值的類型。
var obj = {}; obj.toString() // "[object Object]"
上面代碼調用空對象的toString方法,結果返回一個字符串 object Object,其中第二個Object表示該值的 構造函數。
由于實例對象可能會自定義toString方法,覆蓋掉 Object.prototype.toString方法,所以為了得到類型字符串,最好直接使用Object.prototype.toString方法。通過函數的call方法,可以在任意值上調用這個方法,幫助我們判斷這個值的類型。
Object.prototype.toString.call(value)
上面代碼表示對value這個值調用Object.prototype.toString方法。
返回值不同數據類型的Object.prototype.toString方法返回值如下:
數值:返回 [object Number]。
字符串:返回 [object String]。
布爾值:返回 [object Boolean]。
undefined:返回 [object Undefined]。
null:返回 [object Null]。
Symbol類型:返回 [object Symbol]。
數組:返回 [object Array]。
arguments 對象:返回 [object Arguments]。
函數:返回 [object Function]。
Error 對象:返回 [object Error]。
Date 對象:返回 [object Date]。
RegExp 對象:返回 [object RegExp]。
其他對象:返回 [object Object]。
Object.prototype.toString.call(2) // "[object Number]" Object.prototype.toString.call("") // "[object String]" Object.prototype.toString.call(true) // "[object Boolean]" Object.prototype.toString.call(undefined) // "[object Undefined]" Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(Symbol()) // "[object Symbol]" Object.prototype.toString.call(Math) // "[object Math]" Object.prototype.toString.call({}) // "[object Object]" Object.prototype.toString.call([]) // "[object Array]"封裝實用函數
利用這個特性,可以封裝一個比typeof運算符更準確的類型判斷函數。
var type = function (o){ var s = Object.prototype.toString.call(o); return s.match(/[object (.*?)]/)[1].toLowerCase(); }; type({}); // "object" type([]); // "array" type(5); // "number" type(null); // "null" type(); // "undefined" type(/dora/); // "regexp" type(new Date()); // "date"
在上面這個type函數的基礎上,還可以加上專門判斷某種類型數據的方法。
var dataArr = ["Null", "Undefined", "Object", "Array", "String", "Number", "Boolean", "Function", "RegExp"]; dataArr.forEach(function (t) { type["is" + t] = function (o) { return type(o) === t.toLowerCase(); }; }); type.isObject({}); // true type.isNumber(NaN); // true type.isRegExp(/abc/); // trueinstanceof 運算符
instanceof 運算符返回一個布爾值,表示對象是否為某個構造函數的實例。
function People(){} var person = new People(); person instanceof People // true判斷原理
遍訪對象的原型鏈上的每個原型對象,如果遍訪到這個原型對象,是某個構造函數的prototype,那么就認為對象是這個構造函數的實例,返回true。因此同一個實例對象,可能會對多個構造函數都返回true,因為繼承的子類實例也是父類的實例。
var d = new Date(); d instanceof Date // true d instanceof Object // true
特殊情況
有一種特殊情況,就是左邊對象的原型鏈上,只有null對象。這時,instanceof判斷會失真。
var obj = Object.create(null); typeof obj // "object" obj instanceof Object // false
上面代碼中,Object.create(null)返回一個新對象obj,它的原型是null。右邊的構造函數Object的prototype屬性,不在左邊的原型鏈上,因此instanceof就認為obj不是Object的實例。
只要一個對象的原型不是null,instanceof運算符的判斷就不會失真。
類型判斷instanceof運算符只能用于對象,不適用原始類型的值,且對于undefined和null,instanceof運算符總是返回false。
"hello" instanceof String // false undefined instanceof Object // false null instanceof Object // false
可用于對象,無論是 JavaScript 內置對象或是自定義構造函數生成的對象,都可進行判斷。
[] instanceof Array // true ({}) instanceof Object // true (function(){}) instanceof Function // true /a/ instanceof RegExp // true new Date() instanceof Date // true person instanceof People // trueconstructor 屬性
prototype對象有一個constructor屬性,默認指向prototype對象所在的構造函數。由于constructor屬性定義在prototype對象上面,意味著可以被所有實例對象繼承。因此,正常情況下,所有對象實例都有一個constructor屬性,屬性值指向構造此對象實例的構造函數。
[].constructor === Array // true [].constructor === Object // false window.constructor === Window //truename屬性
如果不能確定對象實例的constructor屬性是什么函數,可通過函數的name屬性,從實例得到構造函數的名稱。
function Foo() {} var f = new Foo(); f.constructor.name // "Foo"類型判斷
基本數據類型
null和undefined是無效的對象,因此是不會有constructor存在的,這兩種類型的數據需要通過typeof來判斷。
number、string、boolean三種數據類型有對應的Number、String、Boolean三個原生對象(包裝對象)。因此,也可用 constructor進行判斷。symbol類型也可判斷。
(333).constructor.name // "Number" "".constructor.name // "String" false.constructor.name // "Boolean" Symbol().constructor.name // "Symbol"
引用數據類型
JavaScript 內置對象或是自定義構造函數生成的對象,都可進行判斷。
new Date().constructor === Date //true [].constructor === Array //true function F(){}; var f = new F(); f.constructor === F // true f.constructor === Object // false不穩定因素
constructor屬性表示原型對象與構造函數之間的關聯關系,有時開發者會因業務關系重寫prototype,原有的constructor會丟失,若沒有同時修改constructor屬性,引用的時候就會出錯,constructor會默認為Object。
function Person(name) { this.name = name; } Person.prototype.constructor === Person // true Person.prototype = { method: function () {} }; Person.prototype.constructor === Person // false Person.prototype.constructor === Object // true
因此,修改原型對象時,一般要同時修改constructor屬性的指向,或者只在原型對象上添加方法,不要重寫prototype。
總結typeof
typeof 可用來判斷基本數據類型和函數,不可以對引用數據類型進行具體的判斷。
Object.prototype.toString.call(value)
Object.prototype.toString.call(value) 可用于判斷多種數據類型:基本數據類型和 JavaScript 內置對象,然而對于一些自定義構造函數生成的對象就不能進行判斷了。
instanceof
instanceof 運算符不適用判斷原始類型的值,只能用于判斷對象,無論是 JavaScript 內置對象或是自定義構造函數生成的對象,都可進行判斷。然而由于繼承的存在,instanceof 判斷也不完全準確,只能用來判斷兩個對象是否屬于原型鏈的關系,而不一定能獲取對象的具體類型。
constructor
constructor 屬性可準確的判斷對象實例是由哪個構造函數生成的,但自定義構造函數生成的對象,往往會因為重寫prototype造成constructor屬性指向不準確,因此使用的時候也要注意一下。
Object(x)的參數為對象時,總是返回該對象,不做轉換;當參數為原始類型時,會轉換為對應的包裝對象的實例,參數為空或者undefined或者null時,返回一個空對象。
function isObject(value) { return value === Object(value); } isObject([]); // true isObject(true); // false判斷是不是 NaN
所有數據類型中,只有NaN不等于它本身
function isNaN(value) { return value !== value; } isNaN(NaN); // true判斷數組的方法 Array.isArray()
除了上文提到的三種方法(toString()、instanceof、constructor)可判斷外,還有一個Array構造函數自帶的方法isArray()
可判斷。
Array.isArray(x)
如果x是數組,則為true; 否則為false。
Array.isArray([]); // true Array.isArray(new Array()); // true Array.isArray(Array.prototype); // true 鮮為人知的事實:其實 Array.prototype 也是一個數組。
使用之前需檢測一下兼容性,對于不兼容的瀏覽器可使用下面的代碼創建該方法。
if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === "[object Array]"; }; }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98922.html
摘要:小汪經過實踐得出以下用途??諗到M的類型也是,這表示在內部,數組本質上只是一種特殊的對象。調用函數時,某個參數未設置任何值,這時就可以傳入,表示該參數為空。前端還是很有未來的下節內容細數實用黑科技二。 showImg(https://segmentfault.com/img/remote/1460000016507838); 前言 只有深入學精一門語言,學其他語言才能更好地舉一反三,觸類...
摘要:你首先需要了解的安全工具之一就是。是另一個可為進行安全漏洞掃描的工具。和相似,是的安全審核工具。和其他容器安全工具不同,使用創建自定義配置文件非常容易。月日,北京海航萬豪酒店,容器技術大會即將舉行。 網絡安全問題的重要性大概毋庸置疑,最近無數關于惡意軟件和安全漏洞的消息已充分證明了這一點。 假如你要管理一個Docker環境,并希望幫助自己的公司或用戶在下一個大漏洞來臨時避免遇到麻煩,那...
摘要:你首先需要了解的安全工具之一就是。是另一個可為進行安全漏洞掃描的工具。和相似,是的安全審核工具。和其他容器安全工具不同,使用創建自定義配置文件非常容易。月日,北京海航萬豪酒店,容器技術大會即將舉行。 網絡安全問題的重要性大概毋庸置疑,最近無數關于惡意軟件和安全漏洞的消息已充分證明了這一點。 假如你要管理一個Docker環境,并希望幫助自己的公司或用戶在下一個大漏洞來臨時避免遇到麻煩,那...
摘要:閑來無事,整理一下中那些神乎其神的技巧,假裝大牛的樣子字符串轉換為數字同樣可用于日期轉換為數值數值向下取整字符串轉換為數值并取整謝謝開始學習前端指正,該取整直接去除小數點后數字,僅對正數有效函數設置默認值為時最后都得到變量值交換使用 閑來無事,整理一下JavaScript中那些神乎其神的技巧,假裝大牛的樣子 1. 字符串轉換為數字 var a = 123; consol...
閱讀 2373·2021-11-24 10:26
閱讀 2565·2021-11-16 11:44
閱讀 1695·2021-09-22 15:26
閱讀 3565·2021-09-10 11:11
閱讀 3178·2021-09-07 10:25
閱讀 3615·2021-09-01 10:41
閱讀 1002·2021-08-27 13:11
閱讀 3498·2021-08-16 11:02