lodash源码分析之数据类型获取的兼容性

栏目: 编程工具 · 发布时间: 7年前

内容简介:焦虑和恐惧的区别是,恐惧是对世界上的存在的恐惧,而焦虑是在"我"面前的焦虑。——萨特《存在与虚无》本文为读 lodash 源码的第十九篇,后续文章会更新到这个仓库中,欢迎 star:

焦虑和恐惧的区别是,恐惧是对世界上的存在的恐惧,而焦虑是在"我"面前的焦虑。

——萨特《存在与虚无》

本文为读 lodash 源码的第十九篇,后续文章会更新到这个仓库中,欢迎 star: pocket-lodash

gitbook也会同步仓库的更新,gitbook地址:pocket-lodash

前言

在前文《 lodash源码分析之获取数据类型 》已经解释了获取数据类型的方法,但是在有些环境下,一些 es6 新增的对象获取到的类型都为 [object Object] ,这样就没办法做细致的区分。例如在 IE11 中,通过 Object.prototype.toString 获取到的 DataView 对象类型为 [object Object] 。 因此在 getTag 中,lodash 针对这些对象做了一些兼容性的事情。

依赖

import baseGetTag from './baseGetTag.js'
复制代码

lodash源码分析之获取数据类型

源码分析

const dataViewTag = '[object DataView]'
const mapTag = '[object Map]'
const objectTag = '[object Object]'
const promiseTag = '[object Promise]'
const setTag = '[object Set]'
const weakMapTag = '[object WeakMap]'

/** Used to detect maps, sets, and weakmaps. */
const dataViewCtorString = `${DataView}`
const mapCtorString = `${Map}`
const promiseCtorString = `${Promise}`
const setCtorString = `${Set}`
const weakMapCtorString = `${WeakMap}`

let getTag = baseGetTag

// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
    (getTag(new Map) != mapTag) ||
    (getTag(Promise.resolve()) != promiseTag) ||
    (getTag(new Set) != setTag) ||
    (getTag(new WeakMap) != weakMapTag)) {
  getTag = (value) => {
    const result = baseGetTag(value)
    const Ctor = result == objectTag ? value.constructor : undefined
    const ctorString = Ctor ? `${Ctor}` : ''

    if (ctorString) {
      switch (ctorString) {
        case dataViewCtorString: return dataViewTag
        case mapCtorString: return mapTag
        case promiseCtorString: return promiseTag
        case setCtorString: return setTag
        case weakMapCtorString: return weakMapTag
      }
    }
    return result
  }
}
复制代码

getTag 的源码很简单,处理的是 DataViewMapSetPromiseWeakMap 等对象,下面就关键的几点说明一下。

函数的toString方法

const dataViewCtorString = `${DataView}`
const mapCtorString = `${Map}`
const promiseCtorString = `${Promise}`
const setCtorString = `${Set}`
const weakMapCtorString = `${WeakMap}`
复制代码

我们都知道, DataView 这些其实都是构造函数,函数有 toString 的方法,调用后返回的是 function DataView() { [native code] } 这样的格式,因为其实例调用 Object.prototype.toString 在某些环境下返回的是 [object Object] ,而构造函数的 toString 返回的字符串中,包含了构造函数名,可以通过这点来区分。

实例中构造函数的获取

const Ctor = result == objectTag ? value.constructor : undefined
 const ctorString = Ctor ? `${Ctor}` : ''
复制代码

每个实例中都包含一个 constructor 的属性,这个属性指向的是实例的构造函数,在获取到这个构造函数后,就可以调用它的 toString 方法,然后就可以比较了。

Promise.resolve

getTag(Promise.resolve()) != promiseTag
复制代码

在条件判断时,使用了 Promise.resolve() ,这样使用的目的是获取到 promise 对象,因为 Promise 是一个函数函数,如果直接调用 Object.prototype.toString ,返回的是 [object Function]


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Purely Functional Data Structures

Purely Functional Data Structures

Chris Okasaki / Cambridge University Press / 1999-6-13 / USD 49.99

Most books on data structures assume an imperative language such as C or C++. However, data structures for these languages do not always translate well to functional languages such as Standard ML, Ha......一起来看看 《Purely Functional Data Structures》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具