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数据类型的五种方法相关推荐

  1. 判断JS数据类型的四种方法

    在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型 和 引用类型 两大类,如下所示: 基本类型:String.Number.Boolean.Symbol.Undefined.N ...

  2. JS深拷贝的五种方法

    1.JSON方法实现 //_tmp和result是相互独立的,没有任何联系,有各自的存储空间. let deepClone = function (obj) {let _tmp = JSON.stri ...

  3. 3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景|判断数组里有没有某对象,有不添加,没有则添加到数组

    3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景 一.当数组中的数据是简单类型时: 应用js中的indexof方法:存在则返回当前项索引,不存在则返回 ...

  4. 用JQuery或JS改变div的id的五种方法

    div的id是可以改变的,通常使用的方法是通过JQuery或Javascript来实现.本文介绍用JQuery或JS改变div的id的五种方法. 方法一:使用Tag选择器 JQuery代码如下: &l ...

  5. 素数(质数)判断的五种方法

    素数判断的五种方法 素数判断是我们写程序过程中经常遇见的一个问题,于是今天我简单地整理一下常用的素数判断的方法. 素数的介绍 素数定义 质数(prime number)又称素数,有无限个.一个大于1的 ...

  6. php判断数组的值是否为空,PHP判断数组是否为空的常用方法(五种方法)

    本文介绍了PHP开发中遇到的数组问题,小编在这里给大家总结了5中方法关于php判断数组是否为空问题,需要的朋友参考下 本文介绍了PHP开发中遇到的数组问题,这里介绍了判断PHP数组为空的5种方法,有需 ...

  7. js获取元素的五种方法

    在使用Javascript的过程中我们经常都需要获取元素 ,接下来就给大家介绍一下我知道的在js中获取元素的五种方法. 1.根据选择器查找元素 1.1  document.querySelector( ...

  8. Js去掉字符串前后空格的五种方法

    第一种:循环检查替换 //供使用者调用 function trim(s){ return trimRight(trimLeft(s)); } //去掉左边的空白 function trimLeft(s ...

  9. 正确判断js数据类型 总结记录

    正确判断js数据类型 总结记录 判断js中的数据类型有一下几种方法:typeof.instanceof. constructor. prototype. 三方库. js六大数据类型 number: 数 ...

最新文章

  1. SCI论文的时态、主动语句和被动语句总结
  2. mysql my.cnf key_buffer_size_mysql5.6之key_buffer_size优化设置-阿里云开发者社区
  3. Mask R-CNN为什么“家喻户晓”
  4. c++ linux 线程等待与唤醒_C++并发编程 等待与唤醒
  5. Seata AT模式
  6. SP2010开发和VS2010专家食谱--第三章节--高级工作流(2)--为沙盒解决方案创建自定义活动...
  7. php创建无限级树型菜单以及三级联动菜单
  8. PostgreSQL 当月最后一天的工作日 , 计算日期是星期几
  9. python在input输入数字为何是str_Python基础笔记:input()输入与数据类型转换
  10. Must read C++ book list
  11. 日前加拿大平板厂商 Datawind和印度运营商Reliance Communications日前宣布合作
  12. nodejs实现redis ORM
  13. The database could not be exclusively locked to perform the operation(SQL Server 5030错误解决办法)(转)...
  14. BI工具怎么选型--BI厂商有哪些--BI系统多少钱--BI工具2019排行
  15. 星际争霸、魔兽争霸3、红色警戒之完全对比
  16. while(i--)和while(--i)的区别
  17. 区块链51%双花攻击
  18. 【Linux】虚拟地址空间 --- 虚拟地址、空间布局、内存描述符、写时拷贝、页表…
  19. 单场GMV翻了100倍,冷门品牌崛起背后的“通用法则”是什么?
  20. [BUUCTF]REVERSE解题记录 [MRCTF2020]Shit

热门文章

  1. ppt中如何加入flash
  2. 大学计算机基础教程复习考试试题
  3. 倾斜摄影后处理软件 Linux版,正射影像倾斜摄影测量软件相关软件汇总
  4. c语言for循环嵌套经典例题,C语言 for循环的嵌套题(含解析和答案).doc
  5. 2022速卖通828年中大促报名玩法规则详解!
  6. 电路板损坏导致电脑识别不到硬盘怎么恢复
  7. 注意stm32定时器的倍频器
  8. 食品检测设备硬件方案
  9. 人工智能(AI)入门
  10. 基于rt-thread与stm32f405rgt6驱动 240x320的st7789v TFT屏