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]