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

資訊專(zhuān)欄INFORMATION COLUMN

JavaScript專(zhuān)題之類(lèi)型判斷(上)

lk20150415 / 1897人閱讀

摘要:專(zhuān)題系列第四篇,講解類(lèi)型判斷的各種方法,并且跟著寫(xiě)一個(gè)函數(shù)。返回值為表示操作數(shù)類(lèi)型的一個(gè)字符串??紤]到實(shí)際情況下并不會(huì)檢測(cè)和,所以去掉這兩個(gè)類(lèi)型的檢測(cè)。

JavaScript專(zhuān)題系列第四篇,講解類(lèi)型判斷的各種方法,并且跟著 jQuery 寫(xiě)一個(gè) type 函數(shù)。

前言

類(lèi)型判斷在 web 開(kāi)發(fā)中有非常廣泛的應(yīng)用,簡(jiǎn)單的有判斷數(shù)字還是字符串,進(jìn)階一點(diǎn)的有判斷數(shù)組還是對(duì)象,再進(jìn)階一點(diǎn)的有判斷日期、正則、錯(cuò)誤類(lèi)型,再再進(jìn)階一點(diǎn)還有比如判斷 plainObject、空對(duì)象、Window 對(duì)象等等。

以上都會(huì)講,今天是上半場(chǎng)。

typeof

我們最最常用的莫過(guò)于 typeof,注意,盡管我們會(huì)看到諸如:

console.log(typeof("yayu")) // string

的寫(xiě)法,但是 typeof 可是一個(gè)正宗的運(yùn)算符,就跟加減乘除一樣!這就能解釋為什么下面這種寫(xiě)法也是可行的:

console.log(typeof "yayu") // string

引用《JavaScript權(quán)威指南》中對(duì) typeof 的介紹:

typeof 是一元操作符,放在其單個(gè)操作數(shù)的前面,操作數(shù)可以是任意類(lèi)型。返回值為表示操作數(shù)類(lèi)型的一個(gè)字符串。

那我們都知道,在 ES6 前,JavaScript 共六種數(shù)據(jù)類(lèi)型,分別是:

Undefined、Null、Boolean、Number、String、Object

然而當(dāng)我們使用 typeof 對(duì)這些數(shù)據(jù)類(lèi)型的值進(jìn)行操作的時(shí)候,返回的結(jié)果卻不是一一對(duì)應(yīng),分別是:

undefined、object、boolean、number、string、object

注意以上都是小寫(xiě)的字符串。Null 和 Object 類(lèi)型都返回了 object 字符串。

盡管不能一一對(duì)應(yīng),但是 typeof 卻能檢測(cè)出函數(shù)類(lèi)型:

function a() {}

console.log(typeof a); // function

所以 typeof 能檢測(cè)出六種類(lèi)型的值,但是,除此之外 Object 下還有很多細(xì)分的類(lèi)型吶,如 Array、Function、Date、RegExp、Error 等。

如果用 typeof 去檢測(cè)這些類(lèi)型,舉個(gè)例子:

var date = new Date();
var error = new Error();
console.log(typeof date); // object
console.log(typeof error); // object

返回的都是 object 吶,這可怎么區(qū)分~ 所以有沒(méi)有更好的方法呢?

Obejct.prototype.toString

是的,當(dāng)然有!這就是 Object.prototype.toString!

那 Object.protototype.toString 究竟是一個(gè)什么樣的方法呢?

為了更加細(xì)致的講解這個(gè)函數(shù),讓我先獻(xiàn)上 ES5 規(guī)范地址:https://es5.github.io/#x15.2.4.2。

在第 15.2.4.2 節(jié)講的就是 Object.prototype.toString(),為了不誤導(dǎo)大家,我先奉上英文版:

When the toString method is called, the following steps are taken:

If the this value is undefined, return "[object Undefined]".

If the this value is null, return "[object Null]".

Let O be the result of calling ToObject passing the this value as the argument.

Let class be the value of the [[Class]] internal property of O.

Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".

凡是規(guī)范上加粗或者斜體的,在這里我也加粗或者斜體了,就是要讓大家感受原汁原味的規(guī)范!

如果沒(méi)有看懂,就不妨看看我理解的:

當(dāng) toString 方法被調(diào)用的時(shí)候,下面的步驟會(huì)被執(zhí)行:

如果 this 值是 undefined,就返回 [object Undefined]

如果 this 的值是 null,就返回 [object Null]

讓 O 成為 ToObject(this) 的結(jié)果

讓 class 成為 O 的內(nèi)部屬性 [[Class]] 的值

最后返回由 "[object " 和 class 和 "]" 三個(gè)部分組成的字符串

通過(guò)規(guī)范,我們至少知道了調(diào)用 Object.prototype.toString 會(huì)返回一個(gè)由 "[object " 和 class 和 "]" 組成的字符串,而 class 是要判斷的對(duì)象的內(nèi)部屬性。

讓我們寫(xiě)個(gè) demo:

console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null)) // [object Null]

var date = new Date();
console.log(Object.prototype.toString.call(date)) // [object Date]

由此我們可以看到這個(gè) class 值就是識(shí)別對(duì)象類(lèi)型的關(guān)鍵!

正是因?yàn)檫@種特性,我們可以用 Object.prototype.toString 方法識(shí)別出更多類(lèi)型!

那到底能識(shí)別多少種類(lèi)型呢?

至少 12 種!

你咋知道的?

我數(shù)的!

……

讓我們看個(gè) demo:

// 以下是11種:
var number = 1;          // [object Number]
var string = "123";      // [object String]
var boolean = true;      // [object Boolean]
var und = undefined;     // [object Undefined]
var nul = null;          // [object Null]
var obj = {a: 1}         // [object Object]
var array = [1, 2, 3];   // [object Array]
var date = new Date();   // [object Date]
var error = new Error(); // [object Error]
var reg = /a/g;          // [object RegExp]
var func = function a(){}; // [object Function]

function checkType() {
    for (var i = 0; i < arguments.length; i++) {
        console.log(Object.prototype.toString.call(arguments[i]))
    }
}

checkType(number, string, boolean, und, nul, obj, array, date, error, reg, func)

除了以上 11 種之外,還有:

console.log(Object.prototype.toString.call(Math)); // [object Math]
console.log(Object.prototype.toString.call(JSON)); // [object JSON]

除了以上 13 種之外,還有:

function a() {
    console.log(Object.prototype.toString.call(arguments)); // [object Arguments]
}
a();

所以我們可以識(shí)別至少 14 種類(lèi)型,當(dāng)然我們也可以算出來(lái),[[class]] 屬性至少有 12 個(gè)。

type API

既然有了 Object.prototype.toString 這個(gè)神器!那就讓我們寫(xiě)個(gè) type 函數(shù)幫助我們以后識(shí)別各種類(lèi)型的值吧!

我的設(shè)想:

寫(xiě)一個(gè) type 函數(shù)能檢測(cè)各種類(lèi)型的值,如果是基本類(lèi)型,就使用 typeof,引用類(lèi)型就使用 toString。此外鑒于 typeof 的結(jié)果是小寫(xiě),我也希望所有的結(jié)果都是小寫(xiě)。

考慮到實(shí)際情況下并不會(huì)檢測(cè) Math 和 JSON,所以去掉這兩個(gè)類(lèi)型的檢測(cè)。

我們來(lái)寫(xiě)一版代碼:

// 第一版
var class2type = {};

// 生成class2type映射
"Boolean Number String Function Array Date RegExp Object Error Null Undefined".split(" ").map(function(item, index) {
    class2type["[object " + item + "]"] = item.toLowerCase();
})

function type(obj) {
    return typeof obj === "object" || typeof obj === "function" ?
        class2type[Object.prototype.toString.call(obj)] || "object" :
        typeof obj;
}

嗯,看起來(lái)很完美的樣子~~ 但是注意,在 IE6 中,null 和 undefined 會(huì)被 Object.prototype.toString 識(shí)別成 [object Object]!

我去,竟然還有這個(gè)兼容性!有什么簡(jiǎn)單的方法可以解決嗎?那我們?cè)俑膶?xiě)一版,絕對(duì)讓你驚艷!

// 第二版
var class2type = {};

// 生成class2type映射
"Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) {
    class2type["[object " + item + "]"] = item.toLowerCase();
})

function type(obj) {
    // 一箭雙雕
    if (obj == null) {
        return obj + "";
    }
    return typeof obj === "object" || typeof obj === "function" ?
        class2type[Object.prototype.toString.call(obj)] || "object" :
        typeof obj;
}
isFunction

有了 type 函數(shù)后,我們可以對(duì)常用的判斷直接封裝,比如 isFunction:

function isFunction(obj) {
    return type(obj) === "function";
}
數(shù)組

jQuery 判斷數(shù)組類(lèi)型,舊版本是通過(guò)判斷 Array.isArray 方法是否存在,如果存在就使用該方法,不存在就使用 type 函數(shù)。

var isArray = Array.isArray || function( obj ) {
    return type(obj) === "array";
}

但是在 jQuery v3.0 中已經(jīng)完全采用了 Array.isArray。

結(jié)語(yǔ)

到此,類(lèi)型判斷的上篇就結(jié)束了,我們已經(jīng)可以判斷日期、正則、錯(cuò)誤類(lèi)型啦,但是還有更復(fù)雜的判斷比如 plainObject、空對(duì)象、Window對(duì)象、類(lèi)數(shù)組對(duì)象等,路漫漫其修遠(yuǎn)兮,吾將上下而求索。

哦, 對(duì)了,這個(gè) type 函數(shù)抄的 jQuery,點(diǎn)擊查看 type 源碼。

專(zhuān)題系列

JavaScript專(zhuān)題系列目錄地址:https://github.com/mqyqingfeng/Blog。

JavaScript專(zhuān)題系列預(yù)計(jì)寫(xiě)二十篇左右,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖、節(jié)流、去重、類(lèi)型判斷、拷貝、最值、扁平、柯里、遞歸、亂序、排序等,特點(diǎn)是研(chao)究(xi) underscore 和 jQuery 的實(shí)現(xiàn)方式。

如果有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,?qǐng)務(wù)必給予指正,十分感謝。如果喜歡或者有所啟發(fā),歡迎 star,對(duì)作者也是一種鼓勵(lì)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83681.html

相關(guān)文章

  • JavaScript專(zhuān)題系列文章

    摘要:專(zhuān)題系列共計(jì)篇,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖節(jié)流去重類(lèi)型判斷拷貝最值扁平柯里遞歸亂序排序等,特點(diǎn)是研究專(zhuān)題之函數(shù)組合專(zhuān)題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實(shí)現(xiàn)模式需求我們需要寫(xiě)一個(gè)函數(shù),輸入,返回。 JavaScript 專(zhuān)題之從零實(shí)現(xiàn) jQuery 的 extend JavaScritp 專(zhuān)題系列第七篇,講解如何從零實(shí)現(xiàn)一個(gè) jQuery 的 ext...

    Maxiye 評(píng)論0 收藏0
  • JavaScript專(zhuān)題系列20篇正式完結(jié)!

    摘要:寫(xiě)在前面專(zhuān)題系列是我寫(xiě)的第二個(gè)系列,第一個(gè)系列是深入系列。專(zhuān)題系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點(diǎn)贊,鼓勵(lì)指正。 寫(xiě)在前面 JavaScript 專(zhuān)題系列是我寫(xiě)的第二個(gè)系列,第一個(gè)系列是 JavaScript 深入系列。 JavaScript 專(zhuān)題系列共計(jì) 20 篇,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖、節(jié)流、去重、類(lèi)型判斷、拷貝、最值、扁平、柯里...

    sixleaves 評(píng)論0 收藏0
  • JavaScript專(zhuān)題從零實(shí)現(xiàn)jQuery的extend

    摘要:不過(guò)的實(shí)現(xiàn)中,多了很多細(xì)節(jié)上的判斷,比如第一個(gè)參數(shù)是否是布爾值,是否是一個(gè)對(duì)象,不傳參數(shù)時(shí)的默認(rèn)值等。 JavaScritp 專(zhuān)題系列第七篇,講解如何從零實(shí)現(xiàn)一個(gè) jQuery 的 extend 函數(shù) 前言 jQuery 的 extend 是 jQuery 中應(yīng)用非常多的一個(gè)函數(shù),今天我們一邊看 jQuery 的 extend 的特性,一邊實(shí)現(xiàn)一個(gè) extend! extend 基本用...

    wangtdgoodluck 評(píng)論0 收藏0
  • JS專(zhuān)題數(shù)組去重

    摘要:將元素作為對(duì)象的鍵,默認(rèn)鍵對(duì)應(yīng)的值為如果對(duì)象中沒(méi)有這個(gè)鍵,則將這個(gè)元素放入結(jié)果數(shù)組中去。 前言 數(shù)組去重在日常開(kāi)發(fā)中的使用頻率還是較高的,也是網(wǎng)上隨便一抓一大把的話(huà)題,所以,我寫(xiě)這篇文章目的在于歸納和總結(jié),既然很多人都在提的數(shù)組去重,自己到底了解多少呢。又或者是如果自己在開(kāi)發(fā)中遇到了去重的需求,自己能想到更好的解決方案嗎。 這次我們來(lái)理一理怎么做數(shù)組去重才能做得最合適,既要考慮兼容性,...

    only_do 評(píng)論0 收藏0
  • JavaScript專(zhuān)題類(lèi)型判斷(下)

    摘要:專(zhuān)題系列預(yù)計(jì)寫(xiě)二十篇左右,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖節(jié)流去重類(lèi)型判斷拷貝最值扁平柯里遞歸亂序排序等,特點(diǎn)是研究和的實(shí)現(xiàn)方式。 JavaScript專(zhuān)題系列第五篇,講解更加復(fù)雜的類(lèi)型判斷,比如 plainObject、空對(duì)象、類(lèi)數(shù)組對(duì)象、Window對(duì)象、DOM 元素等 前言 在上篇《JavaScript專(zhuān)題之類(lèi)型判斷(上)》中,我們抄襲 jQuery 寫(xiě)了一個(gè) typ...

    QLQ 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<