1、typeof 用來檢測數據類型的運算符
->typeof value
->返回值首先是一個字符串,其次裡面包含了對應的數據類型,例如:"number"、"string"、"boolean"、"undefined"、"object"、"function"
->局限性:
1)typeof null ->"object"
2)檢測的不管是數組還是正則都返回的是"object",所以typeof不能判斷一個值是否為數組
->console.log(typeof typeof typeof [12, 23]);//->"string" 兩個或者多個typeof一起使用時,返回值一定是"string";
2、instanceof/constructor
->檢測某一個實例是否屬於某一個類
->我們使用instanceof/constructor可以檢測數組和正則了
console.log([] instanceof Array);//->true
console.log(/^$/ instanceof RegExp);//->true
console.log([] instanceof Object);//->true
console.log([].constructor === Array);//->true
console.log([].constructor === Object);//->false 我們的constructor可以避免instanceof檢測的時候,用Object也是true的問題
console.log({}.constructor === Object);
局限性:
1)用instanceof檢測的時候,只要當前的這個類在實例的原型鏈上(可以通過原型鏈__proto__找到它),檢測出來的結果都是true
var oDiv = document.getElementById("div1");
//HTMLDivElement->HTMLElement->Element->Node->EventTarget->Object
console.log(oDiv instanceof HTMLDivElement);//->true
console.log(oDiv instanceof Node);//->true
console.log(oDiv instanceof Object);//->true
2)基本數據類型的值是不能用instanceof來檢測的
->console.log(1 instanceof Number);//->false
數組創建的兩種方式(對象、正則、函數...)
->對於引用數據類型來說,我們兩種方式創建出來的都是所屬類的實例,而且都是對象數據類型的值,是沒有區別的
var ary = [];
var ary = new Array;
->對於基本數據類型來說,雖然不管哪一種方式創建出來的都是所屬類的一個實例(在類的原型上定義的方法都可以使用),但是字面量方式創建出來的是基本數據類型,而實例方式創建出來的是對象數據類型
var num1 = 1;
var num2 = new Number("1");
console.log(typeof num1,typeof num2);//->"number" "object"
3)在類的原型繼承中,instanceof檢測出來的結果其實是不准確的
function Fn() {}
var f = new Fn;
console.log(f instanceof Array);//->false f不是一個數組,它就是一個普通的實例(普通的對象)
->雖然我們的Fn繼承了Array,但是f沒有length和數字索引哪些東西,所以f應該不是數組才對,但是用instanceof檢測的結果卻是true,因為f雖然不是數組,但是在f的原型鏈上可以找到Array
function Fn() {
}
Fn.prototype = new Array;//->Fn子類繼承了Array這個父類中的屬性和方法
var f = new Fn;
console.log(f instanceof Array);//->true
3、Object.prototype.toString.call(value)
->找到Object原型上的toString方法,讓方法執行,並且讓方法中的this變為value(value->就是我們要檢測數據類型的值)
->toString:一個方法,轉換為字符串數據類型用的方法
每一個數據類型所屬類的原型上都有toString方法,例如:Number.prototype/String.prototype/Array.prototype/Function.prototype...
除了Object上的toString,其他類原型上的toString都是把當前的數據值轉換為字符串的意思
->null和undefined比較的特殊:他們所屬類Null/Undefined的原型上也有toString,只不過不讓我們用而已,不僅如此其實類的原型都給屏蔽了
->HTML元素對象的toString:雖然它的原型鏈很長,但是在其它類的原型上都沒有toString,只有在最底層Object.prototype這上才有
var oDiv = document.getElementById("div1");
oDiv.toString();//->調用的其實也是Object.prototype.toString...
->alert、document.write這兩種輸出的方式其實都是把要輸出的內容先轉換為字符串,然後在輸出的
alert([]);//->""
alert(true);//->"true"
alert({});//->這個就要調用Object.prototype上的toString了 ->?
4、Object.prototype.toString是用來返回對應值的所屬類信息的
var oDiv = document.getElementById("div1");
var obj = {};
oDiv.toString();//->"[object HTMLDivElement]"
obj.toString();//->"[object Object]"
原理:
->obj首先找到原型上toString方法,並且讓toString執行,toString方法執行的時候,裡面的this是obj,同理oDiv.toString(),toString方法中的this是oDiv
->執行toString方法,返回當前方法中this的數據類型 ->"[object 當前this的直屬類]",例如:"[object HTMLDivElement]"/"[object Object]"
Object.prototype.toString.call(12);//->執行原型上的toString,並且讓方法中的this變為12,也就相當於返回的是12的直屬類的信息 ->"[object Number]"
Object.prototype.toString.call("zhufeng");//->"[object String]"
依此類推:
"[object Boolean]"/"[object Null]"/"[object Undefined]"/"[object Object]"/"[object Array]"/"[object RegExp]"/"[object Function]"/"[object Math]"/"[object Date]"...
->所有的數據類型都可以用它來檢測,而且非常的精准
value:要檢測數據類型的值 type:判斷是否為這個數據類型
function isType(value, type) {
var res = Object.prototype.toString.call(value);//-> "[object 直屬類]"
return res === "[object " + type + "]";
98->"[object Array]"
字符串拼接->"[object Array"]"
兩個相等了返回true
}
優化:->忽略第二個傳遞進來參數的大小寫
function isType(value, type) {
var reg = new RegExp("^\\[object " + type + "\\]$", "i");
return reg.test(Object.prototype.toString.call(value));
}
var ary = [];x
var flag = isType(ary, "array");
console.log(flag);//->true說名是數組,false說明不是數組 ->true
flag = isType(1, "string");
console.log(flag);//->false
~function () {
var utils = {}, numObj = {
isNum: "Number",
isStr: "String",
isBoo: "Boolean",
isNul: "Null",
isUnd: "Undefined",
isObj: "Object",
isAry: "Array",
isFun: "Function",
isReg: "RegExp",
isDate: "Date"
}, isType = function () {
var outerArg = arguments[0];
return function () {
var innerArg = arguments[0], reg = new RegExp("^\\[object " + outerArg + "\\]$", "i");
return reg.test(Object.prototype.toString.call(innerArg));
}
};
for (var key in numObj) {
if (numObj.hasOwnProperty(key)) {
utils[key] = isType(numObj[key]);
}
}
window.$type = utils;
}();
//console.log($type);
var ary = [];
console.log($type.isAry(ary));//->true
console.log($type.isFun(ary));//->false