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