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