1.typeof: 語法:typeof 對象 或者 typeof(對象)
返回對象的數據類型:只有原始數據類型:boolean number string undefined function object
因爲最初的BUG致使null的數據類型成爲了object,如今,null 被認爲是對象的佔位符,從而解釋了這一矛盾。
缺陷:對於Array,null,Object對象和其餘自定義對象使用typeof一概返回object;
console.log(typeof(x)); //未聲明x,返回undefined var y = false; console.log(typeof y); //boolean var str = "字符串"; console.log(typeof str); //string var num = 5; console.log(typeof(num)); //number console.log(typeof NaN); //number NaN是一個特殊的數字---非數字 var f1 = function () { }; console.log(typeof f1); //function console.log(typeof null); //object var arr = [1, 2, 3]; console.log(typeof arr); //object var obj = {name: "小偉", age: 15}; console.log(typeof obj); //object var Person = function (name) { this.name = name }; var per = new Person("小王"); console.log(typeof per); //object
2.instanceof 用於測試構造函數的prototype屬性是否出如今對象的原型鏈中的任何位置
解讀:用於判斷某個對象是否是某個構造函數的一個實例,或者是否是某個構造函數的一個後代實例
語法:對象 instanceof 數據類型(或者構造函數名):返回true/false
instanceof的原理:function instance_of(L, R) {//L 表示左表達式,R 表示右表達式
var O = R.prototype;// 取 R 的顯示原型
L = L.__proto__;// 取 L 的隱式原型
while (true) {
if (L === null)
return false;
if (O === L)// 這裏重點:當 O 嚴格等於 L 時,返回 true
return true;
L = L.__proto__;
}
}
即比較對象.__proto__和數據類型(構造函數).prototype,若是相等就爲true,
不一樣就繼續跟着對象的原型鏈,比較對象隱式原型裏的隱式原型與數據類型(構造函數).prototype
根據原型鏈的知識直到原型鏈的最終,指向Object.prototype.__proto__---爲null
console.log(per instanceof Person); //true //per.__proto__指向其構造函數的原型對象Person.prototype,因此返回true console.log(f1 instanceof Function); //true console.log(arr instanceof Array); //true console.log(obj instanceof Object); //true //同理,這些引用類型:Function、Array、Object、均可以視爲一個構造函數 //對於繼承的數據類型:新的實例對象根據原型鏈,數據類型能夠是其構造函數名,也能夠是其祖輩的構造函數名 var Student = function (score) { this.score = score; } Student.prototype = new Person("小李"); var stu = new Student(100); console.log(stu instanceof Student); //true stu.__proto__ == Student.prototype很易理解 console.log(stu instanceof Person); //true /* * 根據原型鏈:stu.__proto__ == Student.prototype == new Person * stu.__proto__.__proto__ == new Person.__proto__ == Person.prototype * * * */
注意:函數
* 在JavaScript中,一切都是一個對象( 或者至少被視爲一個對象) 。
* 惟一的non-objects是基本類型:布爾值,數字,字符串和undefined ,
* 直接聲明的這幾種類型的實例不是object對象,可是能夠訪問其做爲對象的一些屬性和方法?爲何呢?
*
* 在訪問基本類型數據的屬性和方法時會臨時出現一個包裝對象:
* 自動建立基本包裝類型的對象,只執行一行代碼的瞬間以後就會當即銷燬。
這意味着在運行時爲基本包裝類型值添加屬性和方法是無效的。
* 好比只要引用了字符串s的屬性,JavaScript就會將字符串值經過調用new String(s)的方式轉換成對象,成爲了基本包裝類型,
* 這個對象繼承了字符串(String)對象的方法,並被用來處理屬性的引用。一旦屬性引用結束,這個新建立的對象就會被銷燬
*
* instanceof 運算符只對對象有效:因此對於上述的幾個non-object無效,因此判斷他們的數據類型時返回值會是false
*
* 另外:布爾,數字,字符串有其構造函數,若是用其構造函數實例化一個對象,則可使用instanceof判斷其數據類型
*
var y = false; console.dir(y); //只是一個基本布爾值,沒有內部結構 console.log(y instanceof Boolean); //false var z = new Boolean(false); console.dir(z); //利用構造函數建立布爾值,能夠獲得內部結構,具備對象的特徵 console.log(z instanceof Boolean); //true console.log(y.__proto__); //因爲基本包裝類型的存在,能夠臨時訪問其做爲對象的屬性, // 這樣作時,會將y經過調用new Boolean獲得一個臨時的包裝對象,具備對象特徵,可是語句執行結束後就消失 y.name = "布爾false"; console.log(y.name); //undefined,沒法對基本類型添加屬性或方法 //沒法對基元類型的數據聲明屬性和方法,由於他們不是對象, // 能夠利用包裝類型的原理訪問基元類型數據的屬性和方法(若是他們所對應的包裝對象有這個屬性和方法的話,若是沒有,返回undefined很容易理解) console.log(str instanceof String); //false console.log(num instanceof Number); //false
3.借用Object原型裏的一個方法 :Object.prototype.toString.call(對象)
能夠獲得對象的數據類型:包括:String、Number、Boolean、undefined、null、Object、function、Array、Date、Regexp
解決了typeof的缺陷
可是沒法獲得自定義構造函數實例化對象的數據類型(構造函數名),只能得到Object
注意:使用這個方法其實是用call()方法借用Object原型裏的一個方法,不能直接使用對象.toString(),
由於對於一個對象,toString方法是被從新定義了的,是將obj轉換爲字符串的方法,
直接使用對象.toString()根據原型鏈,在訪問到這個重寫的方法時就調用了,不能訪問到Object原型裏的這個同名的方法
console.log(Object.prototype.toString.call(null));//[object Null] console.log(Object.prototype.toString.call(undefined)); //[object Undefined] console.log(Object.prototype.toString.call(y)); //[object Boolean] console.log(Object.prototype.toString.call(str));//[object String] console.log(Object.prototype.toString.call(num));//[object Number] console.log(Object.prototype.toString.call(f1));//[object Function] console.log(Object.prototype.toString.call(arr));//[object Array] console.log(Object.prototype.toString.call(obj));//[object Object] console.log(Object.prototype.toString.call(per));//[object Object] console.log(Object.prototype.toString.call(new Date));//[object Date]