typeof + instanceof+toString+constructor什麼推理javascript數據類型

一個、typeof

JS這些變量是弱類型(這是弱類型)的,它能夠無論用來存儲數據的類型的。javascript

typeof 數據類型可用於檢測給定的變量。可能的返回值:
1. 'undefined' --- 這個值沒有定義;
2. 'boolean' --- 這個值是布爾值。
3. 'string' --- 這個值是字符串。
4. 'number' --- 這個值是數值;
5. 'object' --- 這個值是對象或null;
6. 'function' --- 這個值是函數。

測試:
document.write("typeof(1): " + typeof(1) + "<br>");
document.write("typeof(NaN): " + typeof(NaN) + "<br>");
document.write("typeof(Number.MIN_VALUE): " + typeof(Number.MIN_VALUE) + "<br>")
document.write("typeof(Infinity): " + typeof(Infinity) + "<br>")
document.write("typeof(\"123\"): " + typeof("123") + "<br>")
document.write("typeof(true): " + typeof(true) + "<br>")
document.write("typeof(window): " + typeof(window) + "<br>")
document.write("typeof(document): " + typeof(document) + "<br>")
document.write("typeof(null): " + typeof(null) + "<br>")
document.write("typeof(eval): " + typeof(eval) + "<br>")
document.write("typeof(Date): " + typeof(Date) + "<br>")
document.write("typeof(sss): " + typeof(sss) + "<br>")
document.write("typeof(undefined): " + typeof(undefined) + "<br>")
測試結果:
typeof(1): number
typeof(NaN): number
typeof(Number.MIN_VALUE): number
typeof(Infinity): number
typeof("123"): string
typeof(true): boolean
typeof(window): object
typeof(document): object
typeof(null): object
typeof(eval): function
typeof(Date): function
typeof(sss): undefined
typeof(undefined): undefined
參考資料
http://javaeyetodj.iteye.com/blog/1199125
http://www.cnblogs.com/lidabo/archive/2011/12/29/2305770.html

2、instanceof

在 JavaScript 中,推斷一個變量的類型常常會用 typeof 運算符。在使用 typeof 運算符時採用引用類型存儲值會出現一個問題,無論引用的是什麼類型的對象,它都返回 「object」。html

這就需要用到instanceof來檢測某個對象是否是還有一個對象的實例。java

一般來說。使用 instanceof 就是推斷一個實例是否屬於某種類型。
另外。更重的一點是 instanceof 可以在繼承關係中用來推斷一個實例是否屬於它的父類型。上面的代碼中是推斷了一層繼承關係中的父類,在多層繼承關係中,instanceof 運算符相同適用。

instanceof 檢測一個對象A是否是還有一個對象B的實例的原理是:查看對象B的prototype指向的對象是否在對象A的[[prototype]]鏈上。假設在,則返回true,假設不在則返回false。數組

只是有一個特殊的狀況,當對象B的prototype爲null將會報錯(相似於空指針異常)。函數

測試:this

function Foo(){}
Foo.prototype = new Aoo();//JavaScript 原型繼承
var foo = new Foo();
console.log(foo instanceof Foo)//true
console.log(foo instanceof Aoo)//true

console.log(Object instanceof Object);//true
console.log(Function instanceof Function);//true
console.log(Number instanceof Number);//false
console.log(String instanceof String);//false
console.log(Function instanceof Object);//true
console.log(Foo instanceof Function);//true
console.log(Foo instanceof Foo);//false
參考資料
http://www.studyofnet.com/news/175.html

3、toString

Object.prototype.toString().call(param) 返回param的類型(string,格式是[object class]) 。spa

toString() 方法可把一個邏輯值轉換爲字符串,並返回結果,語法爲:booleanObject.toString()。剛纔我說了,js中的對象都是繼承的Object,這些對象都本身定義的有函數或者重構了Object的部分函數,而且它們都對toString()函數進行了重寫。因此咱們不能像1中直接寫param.prototype.toString()這樣就運行的是param本身重寫後的toString()函數了。

在toString方法被調用時,會運行如下的操做步驟:
1. 獲取this對象的[[Class]]屬性的值.
2. 計算出三個字符串"[object ", 第一步的操做結果Result(1), 以及 "]"鏈接後的新字符串.
3. 返回第二步的操做結果Result(2).
在ES3中,規範文檔並無總結出[[class]]內部屬性一共同擁有幾種,只是咱們可以本身統計一下,原生對象的[[class]]內部屬性的值一共同擁有10種.各自是:"Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object","RegExp", "String".因此Object.prototype.toString()的輸出結果就是這樣的格式的字符串[object Array],[object Boolean]。
因此說toString可以推斷: "Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object","RegExp", "String"以上十種數據類型。




在ES5.1中,除了規範寫的更具體一些之外,Object.prototype.toString方法和[[class]]內部屬性的定義上也有一些變化,Object.prototype.toString方法的規範例如如下:
在toString方法被調用時,會運行如下的操做步驟:
1 假設this的值爲undefined,則返回"[object Undefined]".
2 假設this的值爲null,則返回"[object Null]".
3 讓O成爲調用ToObject(this)的結果.
4 讓class成爲O的內部屬性[[Class]]的值.
5 返回三個字符串"[object ", class, 以及 "]"鏈接後的新字符串.
可以看出。比ES3多了1,2,3步.第1,2步屬於新規則,比較特殊,因爲"Undefined"和"Null"並不屬於[[class]]屬性的值。經統計,可返回的類型有"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"比ES3多了2種各自是arguments對象的[[class]]成了"Arguments"。而不是曾經的"Object",還有就是多個了全局對象JSON,它的[[class]]值爲"JSON"。


.net

最後的最後提醒你們,Object.prototype.toString().call(param)返回的[object class]中class首字母是大寫。像JSON這樣的甚至都是大寫,因此。你們推斷的時候可以都轉換成小寫,以防出錯,Object.prototype.toString().call(param).toLowerCase()就能夠。prototype

測試:指針

document.write("{}.toString.call(1): " + {}.toString.call(1) + "<br>");
document.write("{}.toString.call(NaN): " + {}.toString.call(NaN) + "<br>");
document.write("{}.toString.call(Number.MIN_VALUE): " + {}.toString.call(Number.MIN_VALUE) + "<br>")
document.write("{}.toString.call(Infinity): " + {}.toString.call(Infinity) + "<br>")
document.write("{}.toString.call(\"123\"): " + {}.toString.call("123") + "<br>")
document.write("{}.toString.call(true): " + {}.toString.call(true) + "<br>")
document.write("{}.toString.call(window): " + {}.toString.call(window) + "<br>")
document.write("{}.toString.call(document): " + {}.toString.call(document) + "<br>")
document.write("{}.toString.call(null): " + {}.toString.call(null) + "<br>")
document.write("{}.toString.call(eval): " + {}.toString.call(eval) + "<br>")
document.write("{}.toString.call(Date): " + {}.toString.call(Date) + "<br>")
document.write("{}.toString.call(undefined): " + {}.toString.call(undefined) + "<br>")
document.write("{}.toString.call({}): " + {}.toString.call({}) + "<br>")
document.write("{}.toString.call(sss): " + {}.toString.call(sss) + "<br>")

測試結果:
{}.toString.call(1): [object Number]
{}.toString.call(NaN): [object Number]
{}.toString.call(Number.MIN_VALUE): [object Number]
{}.toString.call(Infinity): [object Number]
{}.toString.call("123"): [object String]
{}.toString.call(true): [object Boolean]
{}.toString.call(window): [object global]
{}.toString.call(document): [object HTMLDocument]
{}.toString.call(null): [object Null]
{}.toString.call(eval): [object Function]
{}.toString.call(Date): [object Function]
{}.toString.call(undefined): [object Undefined]
{}.toString.call({}): [object Object]

參考資料:

http://www.jb51.net/article/42864.htm

4、constructor

在W3C定義中的定義:constructor 屬性返回對建立此對象的數組函數的引用。

就是返回對象相相應的構造函數。

從定義上來講跟instanceof不太一致,但效果都是同樣的
注意: constructor 在類繼承時會出錯
好比:

function A(){};
function B(){};
A.prototype = new B(); //A繼承自B
var aObj = new A();
alert(aobj.constructor === B)// -----------> true;
alert(aobj.constructor === A) //-----------> false;
而instanceof方法不會出現該問題,對象直接繼承和間接繼承的都會報true:
alert(aobj instanceof B) //----------------> true;
alert(aobj instanceof B) //----------------> true;
言歸正傳。解決construtor的問題通常是讓對象的constructor手動指向本身:
aobj.constructor = A; //將本身的類賦值給對象的constructor屬性
alert(aobj.constructor === A) //-----------> true;
alert(aobj.constructor === B) //-----------> false; //基類不會報true了;
測試:
console.log([].constructor == <strong>Array</strong>); // true
console.log({}.constructor == <strong>Object</strong>); // true
console.log("string".constructor == <strong>String</strong>); // true
console.log((123).constructor == <strong>Number</strong>); // true
console.log(true.constructor == <strong>Boolean</strong>); // true
console.log((new Date()).constructor == <strong>Date</strong>);//true

參考資料:http://blog.sina.com.cn/s/blog_51048da70101grz6.html

5、jQuery中的類型推斷

type()方法

type: function( obj ) {
    if ( obj == null ) {
        return String( obj );
    }
    return typeof obj === "object" || typeof obj === "function" ?
        class2type[ core_toString.call(obj) ] || "object" :
        typeof obj;
},
相關文章
相關標籤/搜索