類型判斷是個常見問題,有多種不同的判斷方式,每種方式都有適用的場景。 typeof 操作符返回一個字元串,表示未經計算的操作數的類型。 或者 都可以,括弧為可選的。 類型 | 結果 : |: : Undefined | "undefined" ==Null== | =="object"== Bool ...
類型判斷是個常見問題,有多種不同的判斷方式,每種方式都有適用的場景。
typeof
typeof
操作符返回一個字元串,表示未經計算的操作數的類型。
typeof operand
或者 typeof (operand)
都可以,括弧為可選的。
類型 | 結果 |
---|---|
Undefined | "undefined" |
==Null== | =="object"== |
Boolean | "boolean" |
Number | "number" |
String | "string" |
Symbol(ECMAScript 6 新增) | "symbol" |
==函數對象== | =="function"== |
任何其他對象 | "object" |
typeof 會將 null
和 Object
都返回為 "object", 這樣就無法區分具體的對象類型(Array , Date , Error等)。
註意:其中函數對象特別返回為"function" 。
// 'number'
typeof 1
typeof NaN
typeof Infinity
// 'string'
typeof '1'
// 'boolean'
typeof true
// 'undefined'
typeof undefined
// 'symbol'
typeof Symbol(1)
// 'object'
typeof null
// 'object'
typeof {}
typeof []
typeof new Date()
typeof new Number(1)
// 'function'
typeof function(){}
typeof class A {}
typeof Math.sin
instanceof
instanceof運算符用於測試構造函數的prototype屬性是否出現在==對象==的原型鏈中的任何位置
object instanceof constructor
- 左側參數如果不是對象,將返回false
- 右側參數如果不是構造函數,將報錯
let x = 1;
let y = new Number(1);
x instanceof Number // false 1 不是對象
y instanceof Number // true new Number(1)為對象
// 雖然這種方式測試“x”有原型,但是應該是在獲取的時候,自動進行了對象包裝, 其實獲取的是 new Number(1)
x.__proto__ === Object.getPrototypeOf(x) === Number.prototype
// 沿著原型鏈比對 y.__proto__.__proto__ === Object.prototype , 故返回true
y instanceof Object // true
instanceof 的判斷結果會隨著對象或者構造函數的改變而不同,而不是固定的值
class A {}
class B {}
let a = new A();
a instanceof A // true
a instanceof B // false
// 修改a的 __proto__ 指向
a.__proto__ = B.prototype
a instanceof A // false
a instanceof B // true
instanceof不能判斷原始數據類型,但是可以用來判斷對象具體是那種類型
[] instanceof Array // true
new Error() instanceof Error // true
(/[1-9]+/) instanceof RegExp // ture
new Date() instanceof Date // true
let x = document.querySelectorAll('h1')
x instanceof NodeList // true
···
Object.prototype.toString()
toString()
方法返回一個表示該對象的字元串。預設情況下,toString()
方法被每個Object對象繼承。如果此方法在自定義對象中未被覆蓋,toString()
返回 "[object type]" ,其中type是對象的類型。
待檢測對象也許會重寫toString()
方法,這時就無法檢測toString
來判斷類型。所以要保證能夠檢測類型,需要調用Object.prototype.toString
來進行判斷。如下:
let X = function(x) {
this.name = x
}
let x = new X();
x.toString() // "[object,Object]" 使用繼承的toString
Object.prototype.toString.call(x) // "[object,Object]"
X.prototype.toString = function() { // 重寫父類的toString方法
return 'not type'
}
x.toString() // "not type" 使用重寫後的toString , 就不再返回類型
Object.prototype.toString.call(x) // "[object,Object]"
返回的" [ object, Type]" 不好分辨,可以進行特殊的處理,直接返回類型名稱。
// 獲取類型
function getType(target){
let types = {}
let temp = Object.prototype.toString.call(target)
//types映射類型
'Boolean Number String Null Undefined Symbol Function Array Date RegExp Object Error NodeList'.split(' ').map(value => {
types[`[object ${value}]`] = value.toLowerCase()
})
if (types[temp]) {
return types[temp]
}else if (temp.indexOf('HTML') !== -1) { // 判斷是否為DOM元素
return 'element'
}else {
return
}
}
// 測試
getType(1) // "number"
getType(Symbol(1)) // "symbol"
getType([]) // "array"
getType({}) // "object"
getType(document.querySelectorAll('div')) // "nodelist"
用如上方法,就可以便捷的獲取到類型名稱了。
其他API
判斷值是否是 NaN Number.isNaN()
Number.isNaN()
判斷值是否是 NaN,和全局函數 isNaN() 相比,該方法不會強制將參數轉換成數字,只有在參數是真正的數字類型,且值為 NaN 的時候才會返回 true。
Number.isNaN(NaN); // true
Number.isNaN(Number.NaN); // true
Number.isNaN(0 / 0) // true
Number.isNaN(null); // false
Number.isNaN(37); // false
Number.isNaN("37"); // false
Number.isNaN("NaN"); // false 不會隱式轉換
window.isNaN('NaN') // true 會隱式轉換
判斷值是否為有窮數 Number.isFinite()
Number.isFinite()
方法用來檢測傳入的參數是否是一個有窮數(finite number)。 和全局的 isFinite() 函數相比,這個方法不會強制將一個非數值的參數轉換成數值,這就意味著,只有數值類型的值,且是有窮的(finite),才返回 true
Number.isFinite(Infinity); // false
Number.isFinite(NaN); // false
Number.isFinite(-Infinity); // false
Number.isFinite(0); // true
Number.isFinite(2e64); // true
Number.isFinite('0'); // false, 全局函數 isFinite('0') 會返回 true
判斷值是否為整數 Number.isInteger()
Number.isInteger()
方法用來判斷給定的參數是否為整數。
Number.isInteger(0); // true
Number.isInteger(1); // true
Number.isInteger(-100000); // true
Number.isInteger(0.1); // false
Number.isInteger(Math.PI); // false
Number.isInteger(Infinity); // false
Number.isInteger(-Infinity); // false
Number.isInteger("10"); // false 不會進行隱式轉換
Number.isInteger(true); // false
Number.isInteger(false); // false
Number.isInteger([1]); // false