成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

雜談數(shù)據(jù)類型獲取

newsning / 2001人閱讀

摘要:如果項目中需要頻繁的進行數(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

相關(guān)文章

  • memcache與redis雜談

    摘要:項目下的緩存控制客戶端向服務(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就...

    roundstones 評論0 收藏0
  • memcache與redis雜談

    摘要:項目下的緩存控制客戶端向服務(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就...

    Mr_houzi 評論0 收藏0
  • 【譯】雜談:HTML 5的消息通知機制

    摘要:原文譯文的消息通知機制譯者已經(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...

    付倫 評論0 收藏0
  • 21_09_25 C語言雜談

    摘要:多維數(shù)組本質(zhì)上和一維數(shù)組沒區(qū)別,他的維數(shù)僅僅只是作為比例因子和偏移,拿來計算地址偏移用的,但是多級指針用數(shù)組訪問的時候,他的維數(shù)僅僅只做偏移用,他的過程是加偏移,解引用,加偏移,解引用。。。。 類型 c語言中規(guī)定類型這樣一個事情,主要是出于一個怎樣的原因呢? char sho...

    JerryZou 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<