Prototype源碼淺析——Object部分(二)之類型檢測

來源:互聯網
上載者:User

扯淡:

本來這個《Prototype源碼淺析》是只打算作為學習Prototype的筆記的,不過有時候發現一個問題可以深入一點(雖然還是淺析),就脫離了原來的預期,越來越偏題了。今天的打算本來是寫完Str的,但是寫到變數檢測的時候,發現又可以扯點淡,就又拖累了進程。這個對於項目來說,肯定是不好的,不過對於學習,就不清楚了。

因為自己吃過的虧,所以從一個新手的角度,寫得盡量新手向,新手共勉。

 

這裡我不關心javascript裡面各種類型是怎麼定義的,唯一要指出的是

var str_1 = 'xesam';
var str_2 = new String('xesam');
console.log(str_1 === str_2);

其中str_1和str_2不是同一個東西,先前看到群裡面有個人提到類似的一個問題,所以才想起來的。

檢測一個變數的類型,最常見的就是typeof操作符。

typeof的傳回值是一個字串,一般只能返回如下幾個結果:number,boolean,string,function,object,undefined

但是顯然要是我們想區分Date,RegExp這樣的具體類,typeof就沒有辦法了,於是統一歸結到object裡面

先看一下Prototype裡面的一些定義:

      NULL_TYPE = 'Null',
UNDEFINED_TYPE = 'Undefined',
BOOLEAN_TYPE = 'Boolean',
NUMBER_TYPE = 'Number',
STRING_TYPE = 'String',
OBJECT_TYPE = 'Object',
FUNCTION_CLASS = '[object Function]',
BOOLEAN_CLASS = '[object Boolean]',
NUMBER_CLASS = '[object Number]',
STRING_CLASS = '[object String]',
ARRAY_CLASS = '[object Array]',
DATE_CLASS = '[object Date]',

【這些變數的值是作為規定的結果返回,避免人為錯誤】

回到變數檢測上,

我們看個執行個體:

    var array_1 = [null,undefined,10,NaN,'10',true,function(){}];
var array_2 = [new Function(),new String(),new Number(),new Boolean(true),{},[],/x/,new Error(),new Date()];
var varArray = array_1.concat(array_2);
(function(){
for(var i in varArray){
console.log(typeof varArray[i]);
}
})();

下面是結果:

需要重點注意的幾個是:

null-->object

NaN-->number

帶有new操作符的除了Function之外,全部都是object。

我們按照Prototype的形式,封裝一下這個過程,作為常規的過程,null和undefined這兩個特別的我們先處理掉:

(function(){
//先定義一下類型的表示字串
var typeMap = {
'number' : 'Number',
'boolean' : 'Boolean',
'string' : 'String',
'function' : 'Function',
'object' : 'Object',
'undefined': 'Undefined',
'null' : 'Null'
};
function type(obj){
switch(obj){ //檢測null和undefined
case null:{
return typeMap['null'];
}
case undefined:{
return typeMap['undefined'];
}
}
var objType = typeof obj;
switch(objType){
case 'number' : {
return typeMap['number'];
}
case 'boolean' : {
return typeMap['boolean'];
}
case 'string' : {
return typeMap['string'];
}
case 'function' : {
return typeMap['function'];
}
case 'object' : {
return typeMap['object'];
}
}
}
for(var i in varArray){
console.log(type(varArray[i]));
}
})();

【說明:這裡和Prototype裡面有個不一致的地方,Prototype裡面並沒有用typeof來檢測函數,我這裡用了,注意就行】

或者上面的例子再簡單一點:

    (function(){
function type(obj){
return obj === null ? 'Null' :
obj === undefined ? 'Undefined' :
typeof obj === 'number' ? 'Number':
typeof obj === 'boolean' ? 'Boolean':
typeof obj === 'string' ? 'String':
typeof obj === 'function' ? 'Function': 'Object';
}
for(var i in varArray){
console.log(type(varArray[i]));
}
})();

運行結果:

現在我們分離出來了“基本類型”【我這裡基本類型是指的typeof可以檢測出來的類型,不是指的js的基本類型,大牛不要噴我···】

接下來就是分離object那個裡面的類型了。方法提供兩個:

第一、轉化為字串形式

第二、檢測原型

第一種方法:

先將獲得對象的字串表示形式,獲得字串形式的方法有幾種:

var obj = 'xesam';
obj = ''+obj;
obj = String(obj);
obj = obj.toString();

對於alert和consle這樣的輸出方法,輸出對象的時候,都調用了對象的toString()方法。按理來說,這樣沒什麼問題,但是Date,RegExp,Array等都是重寫了從Object繼承過來的toString的方法的,因此到底返回什麼就無法預測了。

所以要調用,必須使用最原始的Object.prototype.toString。
使用最原始的Object.prototype.toString的局限就是無法判斷自訂的類,除非自訂類重寫了自己的toString方法,但是重寫自訂類的toString方法之後又會引起枚舉(in)的問題(Object第一部分提到過),所以這個需要仔細考慮一下。

具體的實現如下:

   (function(){
function objectType(obj){
obj = Object.prototype.toString.call(obj);
return obj;
}
for(var i in varArray_2){
console.log(objectType(varArray_2[i]));
}
})();

運行結果:

第二種方法就是調用instanceof操作符

比如:

console.log([] instanceof Array);

這就是 variable instanceof constructor的形式。

或者直接判斷constructor。

具體實現:

    (function(){
function objectType(obj){
obj = obj.constructor;
return obj === Array ? '[object Array]':
obj === Boolean ? '[object Boolean]':
obj === Date ? '[object Date]':
obj === RegExp ? '[object RegExp]':
obj === String ? '[object String]':
obj === Function? '[object Function]':
obj === Error ? '[object Error]':
obj === Number ? '[object Number]':'[object Object]'
}
for(var i in varArray_2){
console.log(objectType(varArray_2[i]));
}
})();

運行結果:

這個對於自訂的類,也可以獲得相應的結果,只是稍微變通一下代碼而已。

轉載請註明來自小西山子【http://www.cnblogs.com/xesam/】
本文地址:http://www.cnblogs.com/xesam/archive/2011/12/21/2296146.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.