JavaScript型別檢測
- 前言
- JS基本型別
- 型別檢測
- 1.typeof 判斷基本型別
- 2.instanceof 判斷參考資料型別
- 3.Object.prototype.toString 判斷型別
- 4.constructor判斷型別
- 5.duck type 利用特征來判斷型別
前言
JavaScript是web前端廣泛應用的語言之一,在網頁應用制作、腳本制作、小程式等諸多領域具有不可替代的的地位,筆者學習了一端時間的前端,頗感JS知識點的繁碎,故將學習到的一些知識、思考和感悟記錄下來,JS基本型別
JavaScript的基本型別分為原始基本型別和參考資料型別:
- 原始基本型別:
- number
- string
- boolean
- null
- undefined
- symbol
- 參考資料型別:
- Object
- Function
- Array
- Date
- RegExp
注意:ES5中沒有symbol型別
型別檢測
型別檢測有5中常見的方法:
- typeof
- instanceof
- Object.prototype.toString
- constructor
- duck type
1.typeof 判斷基本型別
使用關鍵字 typeof 回傳的是型別名僅包括以下 7 種:number、string、boolean、undefined、symbol、object、function ,
null和大部分的參考型別都不能用 typeof 進行判斷,
let num = 32
let str = "32"
let bool = true
let nul = null
let undef = undefined
let sym = Symbol()
const obj = new Object()
const arr = new Array()
const fun = new Function()
const date = new Date()
const reg = new RegExp()
console.log(typeof num) //number
console.log(typeof str) //string
console.log(typeof bool) //boolean
console.log(typeof nul) //object
console.log(typeof undef) //undefined
console.log(typeof sym) //symbol
console.log(typeof obj) //object
console.log(typeof arr) //object
console.log(typeof fun) //function
console.log(typeof date) //object
console.log(typeof reg) //object
注意:用typeof判斷null、Array、Date、RegExp等型別結果均為object
2.instanceof 判斷參考資料型別
instanceof利用的是變數的__proto__屬性指向原型的prototype屬性進行型別判斷,需要注意的是,如果對基本資料型別使用直接賦值的方法,則__proto__屬性是不存在的,我們需要使用建構式,
const obj = new Object()
const arr = new Array()
const fun = new Function()
const date = new Date()
const reg = new RegExp()
console.log(obj instanceof Object) //true
console.log(arr instanceof Array) //true
console.log(fun instanceof Function) //true
console.log(date instanceof Date) //true
console.log(reg instanceof RegExp) //true
let num1 = 32
let num2 = new Number(32)
console.log(num1 instanceof Number) //false
console.log(num2 instanceof Number) //true
另外,雖然 instanceof 能夠判斷出arr是Array的實體,但它認為也是Object的實體,這對判斷一個未知參考型別并不友好,
const arr = new Array()
console.log(arr instanceof Array) //true
console.log(arr instanceof Object) //true
原因是 arr.__proto__的__proto__屬性指向Object的原型物件,
對于這種情況,可以換用 constructor 進行判斷,
注意:不同window或iframe間的物件檢測不能使用instanceof !
3.Object.prototype.toString 判斷型別
toString() 是 Object 的原型方法,每一個繼承 Object 的物件都有 toString 方法,
所有使用 typeof 回傳值為 object 的物件都包含一個內部屬性[[class]],這個屬性無法直接訪問,一般通過Object.prototype.toString()來查看,
如果 toString 方法沒有重寫的話,默認回傳當前物件的 [[Class]],其格式為[object Xxx],其中 Xxx 為物件的型別,但除了 Object 型別的物件外,其他型別直接使用 toString 方法時,會直接回傳都是內容的字串,所以我們需要使用call或者apply方法來改變toString方法的執行背景關系,
let num = 32
let str = "32"
let bool = true
let nul = null
let undef = undefined
let sym= Symbol()
const obj = new Object()
const arr = new Array()
const fun = new Function()
const date = new Date()
const reg = new RpgExp()
console.log(Object.prototype.toString.apply(num)) //"[object Number]"
console.log(Object.prototype.toString.apply(str)) //"[object String]"
console.log(Object.prototype.toString.apply(bool)) //"[object Boolean]"
console.log(Object.prototype.toString.apply(nul)) //"[object Null"
console.log(Object.prototype.toString.apply(undef)) //"[object Undefined]"
console.log(Object.prototype.toString.apply(sym) //"[object Symbol]"
console.log(Object.prototype.toString.call(obj)) //"[object Object]"
console.log(Object.prototype.toString.call(arr)) //"[object Array]"
console.log(Object.prototype.toString.call(fun)) //"[object Function]"
console.log(Object.prototype.toString.call(date)) //"[object Date]"
console.log(Object.prototype.toString.call(reg) //"[object RegExp]"
Object.prototype.toString可以判斷null,但習慣上我們用 null===null來判斷是否為null,
4.constructor判斷型別
constructor屬性會回傳變數的建構式,當然也可以利用字串截取獲取建構式名稱進行判斷來獲取布林值,如" ".constructor === String,
let num = 32
let str = "32"
let bool = true
let nul = null
let undef = undefined
let sym= Symbol()
const object = new Object()
const arr = new Array()
const fun = new Function()
const date = new Date()
const reg = new RegExp()
console.log(num.constructor) //? Number() { [native code] }
console.log(str.constructor) //? String() { [native code] }
console.log(bool.constructor) //? Boolean() { [native code] }
console.log(nul.constructor) //Uncaught TypeError: Cannot read property 'constructor' of null
console.log(undef.constructor) //Uncaught TypeError: Cannot read property 'constructor' of undefined
console.log(sym.constructor) //? Symbol() { [native code] }
console.log(obj.constructor === Object) //true
console.log(arr.constructor === Array) //true
console.log(fun.constructor === Function) //true
console.log(date.constructor === Date) //true
console.log(reg.constructor === RegExp) //true
無法用constructor判斷null和undefined,但可以避免使用instanceof時arr的原型物件既可以為Array也可以是Object,
5.duck type 利用特征來判斷型別
在程式設計中,鴨子型別(英語:duck typing)是動態型別的一種風格,在這種風格中,一個物件有效的語意,不是由繼承自特定的類或實作特定的介面,而是由"當前方法和屬性的集合"決定,
“當看到一只鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那么這只鳥就可以被稱為鴨子,”
在鴨子型別中,關注點在于物件的行為,能作什么;而不是關注物件所屬的型別,
例如,在不使用鴨子型別的語言中,我們可以撰寫一個函式,它接受一個型別為"鴨子"的物件,并呼叫它的"走"和"叫"方法,
隨后,在使用鴨子型別的函式中,可以接受一個任意型別的物件,并呼叫它的"走"和"叫"方法,如果這些需要被呼叫的方法不存在,那么將引發一個運行時錯誤,任何擁有這樣的正確的"走"和"叫"方法的物件都可被函式接受,
比如判斷一個物件是否是陣列,可以看這個物件是否擁有push()等方法
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/280369.html
標籤:其他
上一篇:js深度克隆出現錯誤,請求指點
