一文打尽js的数据类型方面的知识,妈妈再也不担心你搞不懂了

193 阅读6分钟

话不多说,开门见山

基本数据类型:

  • number、string、boolean、undefined、null
  • ES6 中新增 Symbol(永不相等,一个独一无二的值,没错,他就是整条街最靓的崽)
  • bigint

可能比较少有同学用过,也就是这个鬼

image.png

引用数据类型:

object 这就是所谓的万物皆对象的这个对象 function函数、array数组、date日期...都属于它

说完了数据类型,我们再来说说 特殊的几个崽

  • NaN 这是一种特殊的数字类型 并且 NaN 与任何数进行任何运算结果都是 NaN image.png image.png

是不是分不清谁是这个内奸?哈哈?

别着急,系统会出手

  1. isNaN() 判断数据是否是NaN, 是返回true,否则返回false
  2. NaN 自身不相等,也就是这个崽已经走火入魔了,六亲不认啊,NaN 与谁都不相等,包括它本身!! 没有破绽就是最大的破绽!!那就有了机会对不对?我们用魔法打败魔法! image.png

额 这个函数写得不是很严谨,因为 {} []来了就会坏菜 小改一下

function isvalueNaN(value) {
    if (typeof value === 'object') {
        return '对象就别来看热闹了好嘛?'
    };
    return value !== value
};

nullundefined

说实话这两个崽也是面试老演员了,没关系,这次让你牢牢记住

null 其实是定义了一个变量,但是此处无值,你也可以理解为值就是 null而且null的类型是object(js的原型链一直往上找,就是nullimage.png 1681121664627.jpg 只截了首尾,要看全部的请自己动手好吗

再来说undefined ,它是 定义了一个变量,但是 没有赋值!!!

var a;
console.log(a);//undefined
var b=null;
console.log(b);//null
typeof b // object

接下来说说类型转换

js的数据类型就这几种,所以提到类型转换大多是将其他的数据类型,转换为 String NumberBoolean

显式类型转换

顾名思义,就是明摆着的,你看得到的,由我们自己写代码去转换的!

1. 转化为 Number 类型:Number()、parseFloat()、parseInt()
2. 转化为 String 类型:String()、toString()
3. 转化为 Boolean 类型: Boolean()

这其中要注意的是:

toString()不能转那俩老演员nullunderfined,小伙子还是功力不够,把控不住啊,String() 就是照单全收了;

Number()可以把任意值转换成数值,但要是有 不是数值的字符,也就只能返回老演员 NaN 了;

Boolean() 会把 0、''(空字符串)、null、undefined、NaN、false 转换成 false ,其它都会转换成 true

隐式类型转换

算术运算符 +、-、+=、++、* 、/、%、<<、&

任何值和字符串做+法时,都会先转换为字符串,然后再做拼接操作;这够简单吧??其实内部也是String()出了力;

任何值做 - 法时,都会将其转换为数字,再做运算,其实内部也是 Number()出了力

image.png

这里就不一一列举了,感兴趣的自己可以试试。说了算术运算符,我们再来说说其他好兄弟

数据比较相关的操作符 >、<、== 、<=、>=、===

image.png

差点把逻辑计算符( &&、!、||、三目运算)搞忘了

! 取反运算;如果对非布尔值取反,则会将其转换为布尔值,再取反,Boolean()表示我其实功能很大。

image.png

还有一些 if, while条件表达式 这儿就不举例了 ifelse 大家应该都写过吧?说没写过的直接叉出去!

所以隐式类型转换也是无处不在的!

到这儿又牵扯出1个老演员

=====

简单来说 == 只是比较值是否相等=== 不仅 比较值是否相等,还要 比较类型是否一样

下面再来说说类型检测

1. typeof :只能返回这6种类型number、string、boolean、object、undefined、function

image.png

所以一般 typeof 用于检测一下基本数据类型,引用数据类型要精确判断的话就有点超纲了。有些同学肯定就急了,那 Array{} 分不清了怎么办?

别着急,系统会出手!

接着往下看,下面就是通常用来检查引用数据类型的方法

2. instanceof : 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。(这儿说到了原型和原型链,不清楚的同学可以看这儿

image.png

需要注意的是:它判断的是是否处于原型链上,只要处于实例的原型链上(可以通过原型链 __proto__ 找到它),检测出来的结果都是true。因为所有原型链的尽头都是 object(万物皆对象),所以就造成了这种状况。

image.png

3. constructor:这个大家应该也很熟悉,构造器。(其实也和原型,原型链有关,因为它始终指向创建当前对象的构造函数)

image.png

需要注意的是:对于nullundefined 是判读不了的 image.png

还有就是constructor是可以被改变的,可以被覆盖,也就不准确了 image.png

到这儿是不是有的同学人都麻了,这怎么每一个都有问题呢?到底有没有一种方法,能让我一把梭????

那我们再来看那个号称一个能打10个的重量级选手Object.prototype.toString.call(),这就是大名鼎鼎的全能方法!

4. Object.prototype.toString.call():它的返回类型的格式为[ Object xxx ]

image.png 是不是三百六十度无死角?是不是很能打???

觉得能得话那就重新认识下吧 它其实是利用 Object.prototype.toString() 方法可以返回当前调用者的对象类型([obejct 对象构造函数名]) 的原理来确定数据类型的

每个对象都有一个 toString() 方法,默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 [object type],其中 type 是对象的类型。

估计又有很多小明要问了,那为什么要加call呢?

请记住,程序员永远是最懒的!!!,他们这样写,一定不是撑得慌!!

Object.prototype.toString()返回的是调用者的类型。那么,不论你toString()本身传入的是啥,Object.prototype.toString() 调用者永远都是Object.prototype

所以,你不加call(),你得到的永远都是 [object Object]call可以改变this指向,使其(Object.prototype.toString())指向我们传入的数据

  • 估计还有小明要问,那我直接调用toString()不行吗?让他顺着原型链去找,我只能呵呵一笑,你可真是大聪明。

因为每个数据类,他们都重写了toString()方法,还记得上面数据类型转换的toString()吗?你看看它返回的是啥呢?

image.png

写在最后

基本数据类型 由于占据的空间大小固定且较小,会被存储在栈当中,也就是变量访问的位置

引用数据类型 存储在堆当中,变量访问的其实是一个指针(堆数据的引用地址,这个地址存在栈区里面),它指向存储对象的内存地址(可这样理解嘛,你在银行存了100万,钱存在银行,你身上只带了一把钥匙)

说到这儿就涉及到栈的后进先出,变量复制引申的 浅拷贝和深拷贝问题。

但是今天已经比较晚了,而且这篇文章里面已经写的比较多了,再多了就显得很杂。如果家人们想了解什么可以直接评论我,我可以优先写