摘要:如果項目中需要頻繁的進行數據類型的判斷與獲取可以考慮進行封裝,簡單的處理與已足夠。
前言
在js中數據我們經常需要判斷或者獲取數據類型,大部分時候我們都是通過type加instanceof來組合判斷數據類型來實現,大部分代碼中對于數據類型的獲取處理都比較丑陋,前段時間看了一下Q的源代碼中對數據類型的判斷與獲取處理,看起來相當簡潔也比較好用,這篇文章來進行一下發散。
typeof在js中我們判斷數據類型經常會用到typeof,比如判斷一個數據是否是一個數字類型
var n = 99; typeof(n) === "number"; // true
這么做有一個缺點,typeof只能判斷js中的基礎數據類型undefined、String、Number、Boolean、Object。如果需要判斷一個數據是不是Array類型,這個時候instanceof就派上用場了。
instanceof官方對于instanceof說明: 運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性(翻譯成人話:判斷對象指向構造函數名稱是否與構造函數名一致),如圖:
判斷一個數據是否是時間類型,一般我們都這樣寫:
var list = []; list instanceof Date; // false
instanceof有一個缺點,只能針對對象類型的數據進行處理,因為只有對象中才包含原型鏈prototype,當然平常我們用到的function數據類型也是對象的一種,還是一圖解千言,看一下js中的數據類型大概明了。
判斷null的數據類型在js中null也是Object中的一個子類型(關于null,可以看這篇文章),但是我們不能通過instanceof去獲取,因為null中并沒有原型鏈prototype,于是我們有了這樣的代碼:
var str = "null"; str === null; // false基礎版本獲取數據類型
當我們并不知道數據類型,但是需要獲這個數據的類型時,大部分童鞋的代碼里面都是這樣寫的:
classString(obj) { if (obj && (obj.__proto__ || obj.prototype)) { if (obj instanceof Array) { return "array"; } if (obj instanceof Function) { return "function"; } // 所有obj的衍生數據都判斷一遍 ... } else if (obj === null) { return "null"; // 返回字符串 } else { return typeof(obj); } }
這樣的代碼很繁雜,這么多的”if else“(俗稱面條代碼),既不美觀,也不實用。
升級版本獲取數據類型function classString(obj) { return ({}).toString.call(obj); } classString(null); // [object Null] classString("string"); // [object String] classString(function(){}); // [object Function] classString(new Date()); // [object Function]
有兩個關鍵方法:一個是call,另一個是Object.prototype.toString方法進行處理。
先看call方法簡短描述:
fun.call(this, arg1, arg2, ...)
call: 調用一個函數, 其具有一個指定的this值和分別地提供的參數(參數的列表)
再看一下關于call參數說明:
在fun函數運行時指定的this值。需要注意的是,指定的this值并不一定是該函數執行時真正的this值,如果這個函數處于非嚴格模式下,則指定為null和undefined的this值會自動指向全局對象,同時值為原始值(數字,字符串,布爾值)的this會指向該原始值的自動包裝對象。
只有當this不存在上下文的時候,this才會指向全局對象(瀏覽器中就是window對象)。
”包裝對象“,并不是一種數據類型,原始數據類型中:字符串、數字、布爾值可以轉換成相應的Number、String、Boolean對應的原生對象(注意是對象,不是值),具體在call中的表現形式如下(左邊等價于右邊):
再舉個栗子?:
999 instanceof Number; // false new Number(999) instanceof Number; // true
關于Object toString方法的簡短說明:
默認情況下,toString()方法被每個Object對象繼承。如果此方法在自定義對象中未被覆蓋,toString() 返回 "[object type]",其中type是對象的類型。
這里的type并不是js5中基礎數據類型相關的type,而是當前對象中__proto__中指向的構造函數名(關于__proto__。
自定義數據類型我們在開發的時候經常需要自定義數據,比如說我們自己創建了一個構建函數F,當我們獲取數據類型的時候期待返回的結果為”[object F]“,代碼如下
var F = function() {} var f1 = new F(); classString(f1); // [object Object]
期待的結果并未返回,原因是因為Object.prototype.toString方法只定義了自帶的對象類型返回,EcmaScript關于Object toString 規范:
我們可以直接重定義Object.prototype.toString:
Object.prototype.toString = function(){ // Do something ... }
這并不是一種很好的行為,一方面容易造成全局污染,另一方面也不利于進行排錯;所以還是老老實實的在方法中判斷吧:
function classString(obj, customize) { if (customize && obj && obj.__proto__.constructor.name) { return "[object " + obj.__proto__.constructor.name + "]"; } return ({}).toString.call(obj); } var F = function() {} var f1 = new F(); classString(f1, true); // [object F] classString(f1); // [object Object]
為什么可以通過__proto__.constructor.name來獲取構造函數名,object與function并不會造成混亂,object與function中的 proto 指向并不是相同的,這里不細講,還是參考關于__proto__。
優化返回格式對于”[object type]“數據返回我們只需要獲取type即可,可以通過正則表達獲取type指,這里不做代碼說明。
其他1、關于call、toString方法平常都是信手拈來使用,沒有深入探究過,探究起來和以前自己腦海中的理解還是有些不同的。
2、 如果項目中需要頻繁的進行數據類型的判斷與獲取可以考慮進行封裝,簡單的處理typeof與instanceof已足夠。
3、上述代碼中只是簡單的示例,部分地方并不是十分嚴謹。
EcmaScript
MDN instanceof
MDN call
MDN types Array
undefined與null有什么區別
關于__proto__與prototype
EcmaScript Object toString
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90689.html
摘要:項目下的緩存控制客戶端向服務端請求頁面的過程中,服務端是可控的。可控的才可優化,優化的重點,即是緩存優化。如此就能提高數據響應的速度,也保護了數據源。雖開啟擴展可管理內存,但所能管理的內存大小是有限的。見下圖的英文注釋注意事項 php項目下的緩存控制 客戶端向服務端請求php頁面的過程中,服務端是可控的。 可控的才可優化,優化的重點,即是緩存優化。 試想?數據存儲在DB中,訪問DB就...
摘要:項目下的緩存控制客戶端向服務端請求頁面的過程中,服務端是可控的。可控的才可優化,優化的重點,即是緩存優化。如此就能提高數據響應的速度,也保護了數據源。雖開啟擴展可管理內存,但所能管理的內存大小是有限的。見下圖的英文注釋注意事項 php項目下的緩存控制 客戶端向服務端請求php頁面的過程中,服務端是可控的。 可控的才可優化,優化的重點,即是緩存優化。 試想?數據存儲在DB中,訪問DB就...
摘要:原文譯文的消息通知機制譯者已經被應用到開發中。所以先要征求用戶的許可而不是直接顯示通知。然后,獲取用戶許可之后,我們可以顯示兩種類型的信息最后執行通知代碼。 原文:HTML 5 Notification 譯文:HTML 5 的消息通知機制 譯者:dwqs showImg(https://segmentfault.com/img/bVks7a); HTML 5 已經被應用到Web...
摘要:多維數組本質上和一維數組沒區別,他的維數僅僅只是作為比例因子和偏移,拿來計算地址偏移用的,但是多級指針用數組訪問的時候,他的維數僅僅只做偏移用,他的過程是加偏移,解引用,加偏移,解引用。。。。 類型 c語言中規定類型這樣一個事情,主要是出于一個怎樣的原因呢? char sho...
閱讀 1648·2021-11-16 11:44
閱讀 2392·2021-10-11 11:07
閱讀 4035·2021-10-09 09:41
閱讀 662·2021-09-22 15:52
閱讀 3185·2021-09-09 09:33
閱讀 2700·2019-08-30 15:55
閱讀 2282·2019-08-30 15:55
閱讀 835·2019-08-30 15:55