javascript的常用检测类型方式原理分析

检测方式一、typeof检测类型

基本语法:
typeof [value]
检测结果返回值:
是一个字符串,包裹着对应的数据类型
适用的检测对象和特征:
1.除null的基本数据类型(原始值类型)
2.function类型
3.检测未声明变量返回一个一个"undefined",不报错
4.检测对象类型不能区分
typeof检测原理:按照计算机二进制值来进行检测,检测速度很快

开发运用:
1.检测基本类型(除null类型外)
2.检测function类型
3.检测浏览器兼容性属性

// 检测实例
let isNull = null,
  num = 122,
  str = '8nnn',
  bl = true,
  ud = undefined,
  arr = [22, 'dd'],
  fn = () => {},
  obj = { ob: 'typeof obj' },
  sym = Symbol('您好'),
  bgin = 100n;

console.log(typeof isNull); // object
console.log(typeof num); // number
console.log(typeof bl); // boolean
console.log(typeof ud); // undefined
console.log(typeof arr); // object
console.log(typeof fn); // function
console.log(typeof obj); // object
console.log(typeof sym); // symbol
console.log(typeof bgin); // bigint

// 从以上检测实例结果来看:
// typeof无法区分基本类型null以及Array Object等引用类型
// typeof null 结果为object 原因是typeof采用二进制识别,认为object类型都是000开头 而null是64个0组成的二进制 因此被识别为object

检测方式二 、instanceof 检测类型
基本语法:
[value] instanceof [constructor],检测一个值(实例)是否为[constructor]类的实例
检测结果返回值:
检测结果返回一个布尔值,true或者false
检测原理:
1.首先检测[constructor]是否存在Symbol.hasInstance属性方法,存在则执行这个方法 [constructor]Symbol.hasInstance
Symbol.hasInstance 在兼容Es6的浏览器中,Function.prototype上具备Symbol.hasInstance方法,所以可以说是所有函数有Symbol.hasInstance。
2.如果浏览器检测中不存在Symbol.hasInstance属性方法,则 按照原型链进行查找检测的「如果当前类的原型对象,出现在检测值的原型链上,则结果是true」
检测特征:
1.检测对象是否为Object实例,结果都是true,所以无法验证是否为标准普通对象
2.instanceof无法处理原始值类型的检测的「检测结果都是false,原因:原始值不具备__proto__」
3.因为原型链指向是可以被修改的,而instanceof完全依赖原型链,所以检测出来的结果“仅供参考”
开发运用:
1.检测是否为某个类的实例
2.偶尔“不需要多么严谨”的数据类型检测,可以用它来处理一下,例如:细分对象

const arr = [1, 33];
//   console.log(arr instanceof Array); // true
//   console.log(arr instanceof Object); // true
//   console.log(arr instanceof RegExp); // false
const throwErr = (value, dataType) => {
  //检测右侧dataType是否是一个函数或者对象
  if (typeof dataType !== 'function') {
    throw new TypeError(`Right-hand side of 'instanceof' is not an object`);
  }

  // 原始值一律返回false 不处理
  if (value === null || /^(object|function)$/.test(value)) {
    return false;
  }
  // 不能存在原型对象
  if (!dataType.hasOwnProperty('prototype')) {
    throw new TypeError(
      `Function has non-object prototype 'undefined' in instanceof check`
    );
  }
};

// 定义_instanceof实现 instanceof 检测原理
const _instanceof= (value, dataType) => {
  // 错误处理
  throwErr(value, dataType);

  // 兼容es6浏览器版本 undefined 存在Symbol.hasInstance
  if (typeof Symbol !== 'undefined') {
    const hasInstance = dataType[Symbol.hasInstance];
    if (hasInstance) return hasInstance.call(dataType, value);
  }

  // 不兼容es6版本浏览器
  let selfProto = Object.getPrototypeOf(value);
  while (selfProto) {
    if (selfProto === dataType.prototype) return true;
    selfProto = Object.getPrototypeOf(selfProto);
  }

  return false;
};

console.log(_instanceof(arr, Array), '手写'); // true
console.log(_instanceof(arr, Object), '手写'); // true
console.log(_instanceof(arr, RegExp), '手写'); // true
console.log(
  _instanceof(arr, () => {}),
  '手写'
); // Function has non-object prototype 'undefined' in instanceof check

检测方式三 、Object.prototype.toString.call
说明:除了Object之外,其他数据类型内置类的原型对象上,也存在tostring方法,只不过都是用来转化为字符串的,只要Object.protitype.toString是可以检测数据类型的,检测固定返回固定形式的"[object Object]"
基本语法:
Object.prototype.toString.call([value])

返回值:“[object Object]” => “[object ?]”
检测原始值,“?”这部分是自己所属的构造函数「null->Null undefined->Undefined」
检测的是对象,可以很精准的区分是哪一种对象(弥补了typeof无法细分对象的弊端)
“?”这部分是啥值:
首先查看[value]值是否具备Symbol.toStringTag这个属性,如果有,属性值是啥,最后“?”这部分就是啥;如果没有,一般是获取自己所属构造函数的名字!!
开发运用:
检测对象(而且是想细分对象),则基于toString这个办法

const toString = Object.prototype.toString;

let isNull = null,
  num = 122,
  str = '8nnn',
  bl = true,
  ud = undefined,
  arr = [22, 'dd'],
  fn = () => {},
  fn1 = function Fn1() {},
  obj = { ob: 'typeof obj' },
  sym = Symbol('您好'),
  bgin = 100n;

console.log(toString.call(isNull)); //[object Null]
console.log(toString.call(str)); //[object String]
console.log(toString.call(num)); //[object Boolean]
console.log(toString.call(bl)); //[object Undefined]
console.log(toString.call(ud)); //[object Boolean]
console.log(toString.call(arr)); //[object Array]
console.log(toString.call(fn)); //[object Function]
console.log(toString.call(new fn1())); //[object Object]
console.log(toString.call(obj)); //[object Object]
console.log(toString.call(sym)); //[object Symbol]
console.log(toString.call(bgin)); //[object BigInt]
console.log(toString.call(() => {})); //[object Function]

// 从检测结果来看 检测类型都比较精准 开发推荐使用该方式对引用类型进行细分

检测方式四 、constructor

	基本语法 [value].constructor===[ctor]
    检测一个值的构造函数是否是XXX,从而判断他的数据类型!
    const arr = [1,22]
   arr.constructor===Array 说明是数组类型
    检测特点:
      1.因为constructor很容易被修改,所以检测的结果“仅供参考”
      2.可以处理原始值「默认“装箱”」
      3.可以区分是否为“标准普通对象”
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐梦想之路_随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值