【源码阅读 | xe-utils源码 | 02】判断Array类型

1. 背景

  上一期了解了JavaScript 基础类型的判断 ,但唯独少了 Array。这期便来讲讲 xe-utils 源码中对是否 Array 的判断。

  如果使用 typeof 来判断 Array 的话,返回的只会是一个 object,如下

const arr = []
console.log(typeof arr) // object

  那源码中是如何判断 Array 的呢?

2. 源码解析

  要判断是否为 Array 类型,不能使用 typeof;也许你想到了,用 Array.isArray 来判断不失为一个好方法,但查看源码后发现其写法如下

2.1 isArray.js

  源码中先尝试用 Array.isArray 进行判断;
  若该方法不存在,则使用 helperCreateInInObjectString 构造出来的方法进行判断

var helperCreateInInObjectString = require('./helperCreateInInObjectString')

var isArray = Array.isArray || helperCreateInInObjectString('Array')

module.exports = isArray

源码为何要这么实现?有两个细节

  1. 【兼容性】Array.isArrayES6 中才有的方法,因此只用 Array.isArray 的话,兼容性不足
  2. 【扩展性】尽管 Array.isArray 可以判断出 Array,但在 JavaScript 中,不止Arraytypeof 判断不出来,诸如此类的还有如下:
typeof new Date(); // object
typeof new Error(); // object
typeof new RegExp(); // object

  为了同时具备兼容性和扩展性,helperCreateInInObjectString 中实现了什么方法呢?

2.2 helperCreateInInObjectString.js

// helperCreateInInObjectString.js
var objectToString = require('./staticObjectToString')

function helperCreateInInObjectString (type) {
  return function (obj) {
    return '[object ' + type + ']' === objectToString.call(obj)
  }
}

module.exports = helperCreateInInObjectString

  上述函数的功能,在于将要判断的值,转化为形如:[object Object] 的字符串形式再进行判断,部分示例如下:

objectToString.call([]) // [object Array]
objectToString.call("") // [object String]
objectToString.call(/\d/) // [object RegExp]

  该方法可以兼容低版本浏览器,且能判断更多类型,从设计模式的角度上看,使用了工厂模式封装了一个公共的判断方法。既实现了向下兼容,也具备可扩展性

  而将值转换为形如 [object Object] 的核心代码 objectToString,内部是如何实现?

2.3 staticObjectToString.js

var objectToString = Object.prototype.toString
module.exports = objectToString

  可以看到,运用了 toString 方法来实现,故在许多工具类中,可以经常见到用该方法 Object.prototype.toString.call(obj) 来获取形如 [object Object] 的字符串。例如 underscore.js 工具类,其实现与本文所提有异曲同工之妙:

// underscore.js
function tagTester(name) {
    var tag = '[object ' + name + ']';
    return function(obj) {
      return toString.call(obj) === tag;
    };
  }

  var isString = tagTester('String');

  var isNumber = tagTester('Number');

  var isDate = tagTester('Date');

  var isRegExp = tagTester('RegExp');

  var isError = tagTester('Error');

  var isSymbol = tagTester('Symbol');

  var isArrayBuffer = tagTester('ArrayBuffer');

  var isFunction = tagTester('Function');
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值