判断JS数据类型的五种方法
JavaScript 中常见的几种数据类型:
目录
JavaScript 中常见的几种数据类型:
一、分类
二、判断
1、typeof
null既然属于基本数据类型,为什么用typeof返回的是object呢?
js小数运算出现的问题(精度丢失)
解决方法一
解决方法二
解决方法三
2、instanceof
3、constructor
细节问题:
4、Object.prototype.toString
5、===
三、相关问题
1、undefined 与 null的区别
2、什么时候给变量赋值为null呢?
3、严格区分变量类型和数据类型?
一、分类
基本类型:string,number,boolean,symbol(ES6新增)基本类型中也有两个特殊的类型,即:undefined,null
引用类型:Object,Function,Array,RegExp,Date,...
二、判断
1、typeof
typeof 返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、object、undefined、function等6种数据类型
typeof '123' string // 有效typeof 1 number // 有效typeof true boolean // 有效typeof Symbol('1') symbol // 有效typeof undefined undefined // 有效typeof {a:1,b:2} object // 有效function c(){console.log('123')}typeof c function // 有效typeof null object // 无效typeof [] ; //object 无效typeof new Date(); //object 无效typeof new RegExp(); //object 无效
总结:typeof 可以对JS基础数据类型做出准确的判断,而对于引用类型返回的基本上都是object, 其实返回object也没有错,因为所有对象的原型链最终都指向了Object,Object是所有对象的`祖宗`。 但当我们需要知道某个对象的具体类型时,typeof 就显得有些力不从心了
null既然属于基本数据类型,为什么用typeof返回的是object呢?
js 在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息?
000:对象
010:浮点数
100:字符串
110:布尔
1:整数
但是对于 undefined 和 null 来说,这两个值的信息存储是有点特殊的。
null:所有机器码均为0
undefined:用 −2^30 整数来表示
所以,typeof 在判断 null 的时候就出现问题了,由于 null 的所有机器码均为0,因此直接被当做了对象来看待。
js小数运算出现的问题(精度丢失)
var num1 = 0.1
var num2 = 0.2
var num3 = num1 + num2
console.log(num3) // 0.30000000000000004
本质原因:计算机对于数据都是转换为二进制存储的,但是对于某些浮点数计算机无法将其精确表达为二进制
像0.5这种数字,可以很快计算得到2进制结果,但是0.1和0.2这样的数字,是永远不可能计算得到准确的2进制结果的,因为一直乘2,就没有得到整数的时候,此时在转换2进制的过程中,会形成无限死循环。
计算机内部在存储无限死循环数据时,必须要有一个限度,采取舍去的原则,所以,0.1和0.2在计算机内部存储的对应的2进制数字,本来就不精准,所以相加得到的2进制结果,也就不精准了,那转换成10进制后,是会有一定的误差的,所以结果不是精准的0.3。
计算机内部对于2进制小数,根据IEEE754标准(是一个仔细制定的表示浮点数及其运算的标准),小数部分最多会保留52位:
所以上面那段代码,在计算机中的运算过程其实是如下所示这样的
0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001
+
0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001
=
0.0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011
所以,不精准是正确的,只是偶尔会有两个不精准的数字相加,正好得到一个精准的值。
解决方法一
将需要运算的小数扩大10倍、100倍、。。。将小数扩大到整数,然后进行运行,最后再缩小扩大的倍数。例:
var num1 = 0.1
var num2 = 0.2
var num3 = (num1 * 10 + num2 * 10) / 10
console.log(num3) // 0.3
解决方法二
通过js中Number的内置方法toFixed,强制保留小数点后位数。例:
var num1 = 0.1
var num2 = 0.2
var num3 = num1 + num2
console.log(num3.toFixed(3)) // 0.300 - 强制保留小数点后3位
解决方法三
封装数学运算方法,当需要进行数学运算的时候,不直接进行,而调用自己封装的方法来实现数学运算。
细说JavaScript中小数点计算不精准的原因和解决方案
2、instanceof
instanceof 是用来判断 A 是否为 B 的实例对,表达式为:A instanceof B,如果A是B的实例,则返回true,否则返回false。 在这里需要特别注意的是:instanceof检测的是原型,我们用一段伪代码来模拟其内部执行过程:
instanceof (A,B) = {var L = A.__proto__;var R = B.prototype;if (L === R) {//A的内部属性__proto__指向B的原型对象return true ;}return false ;
}
从上述过程可以看出,当 A 的 __proto__ 指向 B 的 prototype 时,即A的原型链上可以找到B时,就认为A就是B的实例,我们再来看几个例子:
[] instanceof Array; //true
{} instanceof Object; //true
new Date() instanceof Date; //truefunction Person(){};
new Person() instanceof Person; // true[] instanceof Object; //true
new Date() instanceof Object; //true
new Person instanceof Object; //true
[] 的 __proto__ 直接指向Array.prototype, 间接指向Object.prototype, 所以按照 instanceof 的判断规则,[] 就是Object的实例。当然,类似的new Date()、new Person() 也会形成这样一条原型链,因此,instanceof 只能用来判断两个对象是否属于原型链的关系, 而不能获取对象的具体类型。
3、constructor
当一个函数F被定义时,JS引擎会为F添加prototype原型,然后再在prototype上添加一个constructor属性,并让其指向F的引用。如下所示:
当执行 var f = new F() 时,F被当成了构造函数,f是F的实例对象,此时F原型上的constructor传递到了f上,因此f.constructor == F
可以看出,JS在函数F的原型上定义了constructor,当F被当作构造函数用来创建对象时,创建的新对象就被标记为了“F” 类型,使得新对象有名有姓,可以追溯。
同理,JS中的数据类型也遵守这个规则
细节问题:
- null和undefined是无效的对象,因此是不会有constructor存在的,这两种类型的数据需要通过typeof来判断。
- JS对象的constructor是不稳定的,这个主要体现在自定义对象上,当开发者重写prototype后,原有的constructor会丢失,constructor会默认为Object
4、Object.prototype.toString
toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString运行时this指向的对象类型, 返回的类型格式为[object,xxx],xxx是具体的数据类型,其中包括:String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,... 基本上所有对象的类型都可以通过这个方法获取到。
Object.prototype.toString.call( '' ) ; // [object String]Object.prototype.toString.call(1) ; // [object Number]Object.prototype.toString.call( true ) ; // [object Boolean]Object.prototype.toString.call(undefined) ; // [object Undefined]Object.prototype.toString.call( null ) ; // [object Null]Object.prototype.toString.call( new Function()) ; // [object Function]Object.prototype.toString.call( new Date()) ; // [object Date]Object.prototype.toString.call([]) ; // [object Array]Object.prototype.toString.call( new RegExp()) ; // [object RegExp]Object.prototype.toString.call( new Error()) ; // [object Error]Object.prototype.toString.call(document) ; // [object HTMLDocument]Object.prototype.toString.call(window) ; //[object global] window是全局对象global的引
需要注意的是,必须通过Object.prototype.toString.call来获取,而不能直接 new Date().toString(), 从原型链的角度讲,所有对象的原型链最终都指向了Object, 按照JS变量查找规则,其他对象应该也可以直接访问到Object的toString方法,而事实上,大部分的对象都实现了自身的toString方法,这样就可能会导致Object的toString被终止查找,因此要用call来强制执行Object的toString方法。
5、===
- 可以判断 undefined,null
var a;console.log(a, typeof a, typeof a === 'undefined', a === undefined); // undefined 'undefined' true trueconsole.log(undefined === 'undefined'); // falsea = 3;console.log(typeof a === 'number'); // truea = 'atguigu';console.log(typeof a === 'string'); // true string小写a = true;console.log(typeof a === 'boolean'); // truea = null;console.log(typeof a, a === null); // object true// 2、对象数据类型var b1 = {b2:[1, 'abc', console.log],b3:function(){console.log('b3');return function(){return 'xfzhang';}}};// 判断是否是函数还有一种方式console.log(typeof b1.b3 === 'function'); // true
三、相关问题
实例:实例对象
类型:类型对象
1、undefined 与 null的区别
undefined 代表定义未赋值
null 代表定义并赋值了,只是值为null
2、什么时候给变量赋值为null呢?
初始赋值,表明将要赋值为对象
结束前,让对象称为垃圾对象(被垃圾回收器回收)
3、严格区分变量类型和数据类型?
数据的类型:① 基本类型 ② 对象类型(一般对象类型就是引用类型)
变量的类型(变量内存值的类型): ① 基本类型:保存的就是基本类型的数据 ② 引用类型:保存的是地址值
判断JS数据类型的五种方法相关推荐
- 判断JS数据类型的四种方法
在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型 和 引用类型 两大类,如下所示: 基本类型:String.Number.Boolean.Symbol.Undefined.N ...
- JS深拷贝的五种方法
1.JSON方法实现 //_tmp和result是相互独立的,没有任何联系,有各自的存储空间. let deepClone = function (obj) {let _tmp = JSON.stri ...
- 3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景|判断数组里有没有某对象,有不添加,没有则添加到数组
3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景 一.当数组中的数据是简单类型时: 应用js中的indexof方法:存在则返回当前项索引,不存在则返回 ...
- 用JQuery或JS改变div的id的五种方法
div的id是可以改变的,通常使用的方法是通过JQuery或Javascript来实现.本文介绍用JQuery或JS改变div的id的五种方法. 方法一:使用Tag选择器 JQuery代码如下: &l ...
- 素数(质数)判断的五种方法
素数判断的五种方法 素数判断是我们写程序过程中经常遇见的一个问题,于是今天我简单地整理一下常用的素数判断的方法. 素数的介绍 素数定义 质数(prime number)又称素数,有无限个.一个大于1的 ...
- php判断数组的值是否为空,PHP判断数组是否为空的常用方法(五种方法)
本文介绍了PHP开发中遇到的数组问题,小编在这里给大家总结了5中方法关于php判断数组是否为空问题,需要的朋友参考下 本文介绍了PHP开发中遇到的数组问题,这里介绍了判断PHP数组为空的5种方法,有需 ...
- js获取元素的五种方法
在使用Javascript的过程中我们经常都需要获取元素 ,接下来就给大家介绍一下我知道的在js中获取元素的五种方法. 1.根据选择器查找元素 1.1 document.querySelector( ...
- Js去掉字符串前后空格的五种方法
第一种:循环检查替换 //供使用者调用 function trim(s){ return trimRight(trimLeft(s)); } //去掉左边的空白 function trimLeft(s ...
- 正确判断js数据类型 总结记录
正确判断js数据类型 总结记录 判断js中的数据类型有一下几种方法:typeof.instanceof. constructor. prototype. 三方库. js六大数据类型 number: 数 ...
最新文章
- SCI论文的时态、主动语句和被动语句总结
- mysql my.cnf key_buffer_size_mysql5.6之key_buffer_size优化设置-阿里云开发者社区
- Mask R-CNN为什么“家喻户晓”
- c++ linux 线程等待与唤醒_C++并发编程 等待与唤醒
- Seata AT模式
- SP2010开发和VS2010专家食谱--第三章节--高级工作流(2)--为沙盒解决方案创建自定义活动...
- php创建无限级树型菜单以及三级联动菜单
- PostgreSQL 当月最后一天的工作日 , 计算日期是星期几
- python在input输入数字为何是str_Python基础笔记:input()输入与数据类型转换
- Must read C++ book list
- 日前加拿大平板厂商 Datawind和印度运营商Reliance Communications日前宣布合作
- nodejs实现redis ORM
- The database could not be exclusively locked to perform the operation(SQL Server 5030错误解决办法)(转)...
- BI工具怎么选型--BI厂商有哪些--BI系统多少钱--BI工具2019排行
- 星际争霸、魔兽争霸3、红色警戒之完全对比
- while(i--)和while(--i)的区别
- 区块链51%双花攻击
- 【Linux】虚拟地址空间 --- 虚拟地址、空间布局、内存描述符、写时拷贝、页表…
- 单场GMV翻了100倍,冷门品牌崛起背后的“通用法则”是什么?
- [BUUCTF]REVERSE解题记录 [MRCTF2020]Shit