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