在日常业务开发当中,经常会遇到需要对某种数据类型进行判断,这里介绍几种判断js数据类型的方式~


  1. typepf 关键字
console.log(typeof 1)  // number
console.log(typeof true)  // boolean
console.log(typeof 'shang') // string
console.log(typeof function) // function
console.log(typeof undefined)  // undefinedconsole.log(typeof {})  // object
console.log(typeof [])  // object
console.log(typeof null)  // object

这里要着重注意一下后三个类型鉴定:

typeof {} === 'object',看起来好像没什么问题,然而后面的[]和null就有点花头了.

首先,我们先来聊一下为什么typeof [] === object.

其实在js中,数组本身就是一种特殊的'对象',且作为复杂数据类型的对象和数组的具体值都是存储在堆当中,而栈中仅仅存储了一个指向堆地址的指针,所以这里可以理解为typeof将数组解析成了对象.

而null最有意思,首先null本来就是js设计过程中的一个意外,属于由于设计错误不得不保存的一种数据类型

而要理解typeof null === 'object'的原理,我们不得不聊一下typeof的原理.

首先typeof是通过侦测js在底层储存变量时,在变量机器码中保存的1-3位类型信息来判定返回值的,例如:

000: object
010: float
100: string
110: boolean
1: int

而对象和数组都是 000,所以typeof [] === object

再者,由于null对应的类型机器码也为1-3位的0,所以同样typeof在判定的过程中同样返回了 'object'

那么,我们还能不能用typeof来判定数据是否为null呢?

那必须的呀

!null && typeof null === 'object' // 直接搞定~


2. constructor属性

相信每个了解原型链的同学都对constructor这个属性不陌生,实例的constructor指向的是实例的构造函数,那么我们可以这样:

console.log((1).constructor === Number) // true
console.log(('shang').constructor === String) // true
console.log((true).constructor === Boolean) // true
console.log(([]).constructor === Array) // true
console.log((function() {}).constructor === Function) // true
console.log((() => {}).constructor === Function) // true
console.log(({}).constructor === Object) // true

写到这里,我只想说两个字: 精彩~

看起来好像挺完美的了,对吧?

但是相信很多同学也发现了,实际开发中我们很少使用这种方法,为啥呢?

首先,我们上面测试的很多都是字面量,实际开发中我们们常常面向对象使用复杂的继承方法,那么,我们就无法保证所测试的变量的构造器是否还是对应数据类型原有的构造器.

而且,这种方式只能对比到一层的构造器,对其原型链上节点所对应的构造器并没有办法判断,所以开发中还是尽量少用来的稳妥一些


3. instanceof

instanceof这个关键字,顾名思义,就是 [被判断类型] 是否是该 [类型] 的实例?

换句话说,也就是说instanceof会判定该[类型]的原型是否出现在[被判断类型]的原型链上

看到这是不是完全看懵了?

没事,其实我写的也有点懵,我们直接看着代码来,一下子就清晰了

console.log(new Number(1) instanceof Number) // true
console.log(new String('shang') instanceof String) // true
console.log(new Boolean('true') instanceof Boolean) // true
console.log([] instanceof Array) // true
console.log({} instanceof Object) // true
console.log(function() {} instanceof Function) // true

看起来,好像也挺好用的,实际上坑却非常多,比如:

console.log([] instanceof Object) // true
console.log(() =>{} instanceof Function) // Uncaught SyntaxError: Unexpected token 'instanceof'

出现上面这种问题的原因在于Object的原型也在[]的原型链上,所以才会返回true,这意味着我们的类型判断开始变得没有那么准确了

而下面的问题在于() => {} 会导致instanceof的解析错误,如果想要避免需要在函数外围包上()

console.log((() =>{}) instanceof Function) // true 完美解决

而且,今天既然要聊一下类型判定的原理,我们当然要从js层面上实现一下instanceof

function new_instanceof(leftValue, rightValue) {if(!leftValue){return false;}{let leftPrototype = leftValue.__protp__;let rightPrototype = rightValue.prototype;if(leftPrototype  === rightPrototype ) {return true;} else {new_instanceof(leftPrototype, rightPrototype)}}
}


4. Object.prototype.toString.call()

这种方法是最推荐使用的一种辨别数据格式的方法,他使用了Object构造函数原型上的toString方法,再通过call或者apply绑定当前需要辨别类型数据的context.

console.log(Object.prototype.toString.call(123)) // [object Number]
console.log(Object.prototype.toString.call('shang')) // [object String]
console.log(Object.prototype.toString.apply(true)) // [object Boolean]
console.log(Object.prototype.toString.apply(undefined)) // [object Undefined]
console.log(Object.prototype toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call([123])) // [object Array]
console.log(Object.prototype.toString.call({shang: 'jian'})) // [object Object]
console.log(Object.prototype.toString.apply(Symbol(123))) // [object Symbol]

这里可能有的同学会有疑问,为什么这里要使用Object的原型而不是用诸如Function或者Array的原型上的toString方法呢?

了解过原型链的同学一定清楚,大多数数据类型的原型链都指向Object,这意味着Object原型上的方法会非常的"公用",会统一返回如[object 构造函数名]的字符串,而Array等构造函数的原型上的toString方法在处理自己的实例时往往会返回"奇怪"的东西(和处理其他数据类型格式不一致).

这样会导致"公用"性变差,所以Object.prototype.toString.call成了大家约定俗称的类型判定方式,在日常开发,例如深克隆等的实现上,应用非常多~

前端解析token中的数据_[前端基础]数据类型判定原理解析相关推荐

  1. java 获取自定义参数类型_Springboot中使用自定义参数注解获取 token 中用户数据...

    使用自定义参数注解获取 token 中User数据 使用背景 在springboot项目开发中需要从token中获取用户信息时通常的方式要经历几个步骤 拦截器中截获token TokenUtil工具类 ...

  2. sql server解析xml属性为表格_[Mybatis][基础支持层]mapper xml sql 解析

    该系列文章针对 Mybatis 3.5.1 版本 Mybatis 中 标签解析,主要是为了得到两大部分数据 1.Mapper.class 接口 2.SQL 执行语句,结果集映射关系等数据 在上一章中提 ...

  3. spark启动的worker节点是localhost_Spark大数据在线培训:Spark运行原理解析

    在大数据技术框架当中,Spark是继Hadoop之后的又一代表性框架,也是学习大数据当中必学的重点技术框架.在这些年的发展当中,Spark所占据的市场地位,也在不断拓展.今天的Spark大数据在线培训 ...

  4. 对前端来说token代表了什么_在线公开课 | 前端工程师如何突破瓶颈更好地变现自己...

    课程概要 此次课程的分享主题是"前端工程师如何突破瓶颈更好地变现提升自己".课程从以下三个方面入手,为大家详解一个前端工程师是如何一步步完善并提升自己的的. 前端工程师所应具备的能 ...

  5. 前端和后端开发人员比例_前端开发人员vs后端开发人员–实践中的定义和含义

    前端和后端开发人员比例 Websites and applications are complex! Buttons and images are just the tip of the iceber ...

  6. vue 怎么样不重复往数组里插入数据_前端数据结构与算法(1) -二分查找vs二叉树...

    今天给大家开始介绍前端方面的数据结构,刚把vue源码过完就开始数据结构,可见它的地位有多重要.有人说我一前端又不是后端学这个数据结构干嘛,好吧,只能说你还没有这个意识,一是面试很多大厂就会考察,我面试 ...

  7. FineUI中用JS在前端与后端中传数据

    (如果哪位大神有更好的方法,拜谢赐教!~) 这段时间做的传数据,传的都是字符串. 不管是传值还是传JSON,都是先转变成字符串,再做处理. 一.用JS从前端传数据到后端 1.前端<body> ...

  8. css 浏览器调试中不可见_前端入门必会的初级调试技巧

    本文仅仅针对前端初学者,目的是[用20%不到的时间] 学会[前端最常用的部分调试技巧],如果需要最详细的调试技巧,包括调试性能优化的相关知识,文末会补充最全的文档(chrome devtool的官方文 ...

  9. hbase中为何不能向表中插入数据_大数据HBase理论实操面试题

    1.HBase的特点是什么? 1)大:一个表可以有数十亿行,上百万列: 2)无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列: 3)面向列: ...

最新文章

  1. 纽大副教授炮轰NeurIPS、AAAI等顶会:无聊、就不该继续存在
  2. 大数据WEB阶段 TransientDateAccessResourceException
  3. LOJ#2087 国王饮水记
  4. 大数据架构如何挑选机器.
  5. 统计gitlab代码行脚本_详解代码统计工具cloc--计算文件数、空白行数、注释行和代码行...
  6. 阻尼衰减曲线用python_高阻尼隔震橡胶支座结构及防震效果
  7. Android之稍微靠谱点的透明Activity(不获取触摸事件)
  8. 怎样定义和引用一维数组,二维数组
  9. 中国电子科技集团公司第三十八研究所(合肥9月29日)
  10. redis主从架构宕机问题解决方法
  11. 【机器人控制架构】控制系统架构【控制流程图、控制算法】
  12. rk3288 android7.1.2 4g模块调试(四)
  13. 无线PLC专用数据终端应用方案
  14. 计算机两个账户共享文件,两台电脑如何共享文件,简简单单六步即可实现文件共享...
  15. 计算机一级单元格填充,电脑Excel表格怎么对不连续的单元格进行批量填充
  16. 禁用Android底部虚拟按键
  17. 微信图文编辑器如何添加超链接?
  18. Springboot项目install打包-某些输入文件使用了未经检查或不安全的操作。分析与解决
  19. 地址总线、数据总线和控制总线简述
  20. Android 内存检测工具

热门文章

  1. OpenAI API 案例
  2. FastReport数据库连接路径及软件的最终分发数据库路径问题
  3. 使用labelme进行图片语义分割数据的标注(如何转换为训练的灰度图,即像素值为类别值)
  4. python 去掉字符串第一个字符_10 个 Python 字符串处理技巧
  5. 一线互联网公司中,Java开发的招聘标准
  6. python中if continue else,python基础;if else;for;while 分支处理.continue,break
  7. python day33
  8. 注入学习(3) Mysql+php注入 基于bool和时间的盲注
  9. 终章-剑之魂【模拟】【贪心】
  10. jQuery Mobile开发的新闻阅读器,适应iphone和android手机