js判断数据类型的方法及原理

判断数据类型的方法及原理

1.typeof
原理: 不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位存储其类型信息。
000: 对象 、010: 浮点数 、100:字符串 、110: 布尔 、1: 整数
例:console.log(typeof 100); // number
注:typeof null 为"object",因为null的二进制表示全为0.
typeof 只能判断基础数据类型(null 除外),当判断其它数据类型时,它总是返回 object 或者 function

2.instanceof
原理: 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
(A instanceof B,判断构造函数B的prototype是否在对象A的原型链上)
例:
[] instanceof Object; // true 解析:[].__proto__.__proto__ === Object.prototype
{} instanceof Object; // true 解析:{}.__proto__ === Object.prototype
判断引用数据类型可能不准确,且无法判断基本数据类型,因为基本数据类型没有原型链,除非是用构造函数创建的数据。

  let x = 123
  console.log(x instanceof Number); //false
  
  let a = new Number(123)
  console.log(a instanceof Number) //true

3.constructor
原理: 查找数据的构造函数constructor属性。
可判断所有数据类型(除了undefined和null)。

  console.log((undefined).constructor == undefined);//Cannot read properties of undefined (reading 'constructor')
  console.log((null).constructor == Null);//Cannot read properties of undefined (reading 'constructor')
  console.log((123).constructor == Number);//true
  console.log('1'.constructor == String);//true
  console.log(true.constructor == Boolean);//true
  console.log([].constructor == Array);//true
  console.log(function () { }.constructor == Function);//true
  console.log({}.constructor == Object);//true

注:当修改其构造函数,constructor属性不会修改,所以用来判断数据类型可能不准确。

  function Fun () { }
  Fun.prototype = new String()
  let fn = new Fun()
  console.log(fn.constructor == String); //true

  Fun.prototype = new Number()
  console.log(fn.constructor == String); //true

4.Object.prototype.toString.call()
等同于jQuery中的$.type().
原理: 获取 this 对象的 [[Class]] 属性的值,[[Class]] 是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性,在es6中,[[Class]] 被废弃,而用 [[NativeBrand]]代替,用来识别某个原生对象是否为符合本规范的某一种特定类型的对象。规定使用Object.prototype.toString方法,返回格式为 [object XXXX]

  console.log(Object.prototype.toString.call([]) == '[object Array]'); //true
  console.log(Object.prototype.toString.call(null) == '[object Null]'); //true
  console.log(Object.prototype.toString.call(undefined) == '[object Undefined]'); //true

为什么要用call?
Object.prototype.toString原始作用就是获取对象类型

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

但是当基本数据类型使用toString时,是转化为字符串,因为js将基本数据类型原型上的toString方法重写了。

  let val = [1, 2, 3]
  console.log(val.toString()); //1,2,3
  console.log(Array.prototype.toString.call(val)); //1,2,3
  
  delete Array.prototype.toString
  console.log(val.toString()) //[object Array]

val.toString()等同于Array.prototype.toString.call(val),即调用构造函数中的原型方法。

当我们删除数据原型上的toString方法,再次调用toString方法时,js找不到Array原型上的方法,只能沿着原型链向上查找,找到并继承Object原型上的toString方法,执行后返回数据类型[object Array]。
如果想直接使用顶层对象的原型方法,就要用call将val的上下文指向Object,val可以执行Object原型上的toString(),可判断val的数据类型。

5.isArray (es5新增,仅判断数组)
原理:
(1).先判断vlaue是否为对象类型,不是则返回false
(2).判断Object.prototype.toString.call(value) == '[object Array]'

  Array.isArray([]); //true
  Array.isArray([1]); //true
  Array.isArray(new Array()); //true
  Array.isArray(new Array("a", "b")); //true
  Array.isArray(new Array(2)); //true
  // Array.prototype 也是一个数组
  Array.isArray(Array.prototype); //true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值