怎樣推斷js中的類型呢,先舉幾個樣例:
var a = "jason";
var b = 123;
var c = true;
var d = [1,2,3];
var e = new Date();
var f = function(){
alert('jason');
};
一、最常見的推斷方法:typeof
typeof是一個一進制運算符,它傳回的結果始終是一個字元串,對不同的操作數,它傳回不同的結果,另外typeof能夠推斷function的類型;在推斷除Object類型的對象時比較友善。
console.log(typeof a == "string"); //true
console.log(typeof a == String); //false
詳細的規則例如以下:
1) 對于數字類型的操作數而言, typeof 傳回的值是 number。比方說:typeof 1,傳回的值就是number。
上面是舉的正常數字,對于很規的數字類型而言,其結果傳回的也是number。比方typeof NaN,NaN在JavaScript中代表的是特殊非數字值,盡管它本身是一個數字類型。
在JavaScript中,特殊的數字類型還有幾種:
Infinity //表示無窮大特殊值
NaN //特殊的非數字值
Number.MAX_VALUE //可表示的最大數字
Number.MIN_VALUE //可表示的最小數字(與零最接近)
Number.NaN //特殊的非數字值
Number.POSITIVE_INFINITY //表示正無窮大的特殊值
Number.NEGATIVE_INFINITY //表示負無窮大的特殊值
以上特殊類型,在用typeof進行運算進,其結果都将是number。
2) 對于字元串類型,typeof傳回的值是string。比方typeof "jason"傳回的值是string。
3) 對于布爾類型,typeof傳回的值是boolean。比方typeof true傳回的值是boolean。
4) 對于對象、數組、null傳回的值是object。比方typeof {},typeof [],typeof null傳回的值都是object。
5) 對于函數類型,傳回的值是function。比方:typeof eval,typeof Date傳回的值都是function。
6) 假設運算數是未定義的(比方說不存在的變量、函數或者undefined),将傳回undefined。比方:typeof jason、typeof undefined都傳回undefined。
console.log(typeof a); //string
console.log(typeof b); //number
console.log(typeof c); //boolean
console.log(typeof d); //object
console.log(typeof e); //object
console.log(typeof f); //function
console.log(typeof 1); //number
console.log(typeof NaN); //number
console.log(typeof Number.MIN_VALUE); //number
console.log(typeof Infinity); //number
console.log(typeof "123"); //string
console.log(typeof true); //boolean
console.log(typeof {}); //object
console.log(typeof []); //object
console.log(typeof null); //object
console.log(typeof eval); //function
console.log(typeof Date); //function
console.log(typeof sss); //undefined
console.log(typeof undefined); //undefined
二、推斷一個對象是否為某一資料類型,或一個變量是否為一個對象的執行個體:instanceof
注意:instanceof 後面一定要是對象類型,而且大寫和小寫不能錯,該方法适合一些條件選擇或分支。
console.log(d instanceof Array); //true
console.log(e instanceof Date); //true
console.log(f instanceof Function); //true
三、依據對象的constructor推斷:constructor
console.log(d.constructor === Array) //true
console.log(e.constructor === Date) //true
console.log(f.constructor === Function) //true
注意constructor在類繼承時會出錯
比如:
function A(){};
function B(){};
var aObj = new A();
console.log(aObj.constructor === A); //true;
console.log(aObj.constructor === B); //false;
function C(){};
function D(){};
C.prototype = new D(); //C繼承自D
var cObj = new C();
console.log(cObj.constructor === C); //false;
console.log(cObj.constructor === D); //true;
而instanceof方法不會出現該問題,對象直接繼承和間接繼承的都會報true:
console.log(cObj instanceof C); //true
console.log(cObj instanceof D); //true
解決construtor的問題一般是讓對象的constructor手動指向自己:
cObj.constructor = C; //将自己的類指派給對象的constructor屬性
console.log(cObj.constructor === C); //true;
console.log(cObj.constructor === D); //false; 基類不會報true了;
四、通用但非常繁瑣的方法:prototype
console.log(Object.prototype.toString.call(a) === '[object String]'); //true
console.log(Object.prototype.toString.call(b) === '[object Number]'); //true
console.log(Object.prototype.toString.call(c) === '[object Boolean]'); //true
console.log(Object.prototype.toString.call(d) === '[object Array]'); //true
console.log(Object.prototype.toString.call(e) === '[object Date]'); //true
console.log(Object.prototype.toString.call(f) === '[object Function]'); //true
注:大寫和小寫不能寫錯,比較麻煩,但勝在通用。