JavaScript中的数据类型
JavaScript中的数据类型虽然看上去并不复杂,但有些特性会使新人在刚接触时产生一些困惑,这里总结梳理一下,以供参考。
目录
一、基本定义
JavaScript 是一种弱类型或者说动态语言。最新的 ECMAScript 标准定义了 7 种数据类型:
6 种原始类型(非对象并且无方法的数据)Boolean、Null、Undefined、Number、String、Symbol (ECMAScript 6 新定义)
和 Object(对象)
在网上的一些文章教程里,我们可以看到其他的称呼,例如,原始类型又可以称作基本类型、基本数值、基本数据类型、值类型 ; Object(对象)又可以称作复杂数据类型、引用类型。
所有的基本类型都是不可改变的,即除 Object 以外的所有类型都是不可变的(值本身无法被改变)。例如,与C语言不同,JavaScript 中字符串是不可变的,JavaScript 中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变。我们称这些类型的值为“原始值”。
在一些其他文章教程中往往还能看到Array、Date、RegExp、Function等,这些本质上都是对象,可以在MDN的JavaScript标准库中找到。
二、基本类型(包裹)对象
在查看MDN的JavaScript标准库时,会发现String对象、Number对象、Boolean对象、Symbol对象,这就有点让人困惑,刚才不是说这几个属于基本类型吗?为什么又出现在对象里?
在JS中,除了null和 undefined之外,所有基本类型值都有包裹这个基本类型值的等价对象(String对象、Number对象、Boolean对象、Symbol对象),这些包裹对象的valueOf()方法返回基本类型值。嗯,以上的解释是MDN中的,是不是还是感觉没搞清楚?还是来操作实验一下好了~
typeof 操作符可以用于判断数据类型。
F12打开浏览器的控制台,用两种不同方式创建变量a、b,可以看出来二者属于不同类型,使用Number对象new出来的b是属于object对象。那么使用上有哪些区别呢?我们接着操作~
创建变量c,赋值为a+b,嗯,居然可以计算。
创建变量d,赋值valueOf(),发现d是number类型,嗯,这就是上文所说的包裹对象的valueOf()方法返回基本类型值。
我们接着再提供参数数值6,用Number对象new出来个a2,显然a2是一个object对象,但是我们还是来看看a和a2是否相等。使用“==”与“===”得出了完全不同的结果,“==”居然让一个数值与一个对象相等了?所以说“==”不靠谱,不要使用啊!
接下来的说明涉及到原型链、构造函数,如果不明白建议先去学习一下,反正对于新人来说搞不清楚这些基本类型的对象一般也不会影响继续学习JS......
instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性。
两个变量str与str2,前者是字符串,后者是字符串对象。在字符串构造函数String()(即用于构造字符串对象str2的构造函数String())的prototype上自定义一个方法myStr。instanceof的结果显示字符串str与字符串构造函数String好像没什么关系,毕竟我们创建str的时候看上去确实没调用String()嘛~
然后 .length返回字符串长度,发现二者都能正确返回值,再 .myStr(),都返回"My String!"。好了,这里问个问题,为什么通过字符串字面量 (通过单引号或双引号定义) 定义出来的基本类型的str也会有 .length属性.myStr()方法呢? 我们可以在MDN的String对象里找到这么一段话:
字符串字面量 (通过单引号或双引号定义) 和 直接调用 String 方法(没有通过 new 生成字符串对象实例)的字符串都是基本字符串。JavaScript会自动将基本字符串转换为字符串对象,只有将基本字符串转化为字符串对象之后才可以使用字符串对象的方法。当基本字符串需要调用一个字符串对象才有的方法或者查询值的时候(基本字符串是没有这些方法的),JavaScript 会自动将基本字符串转化为字符串对象并且调用相应的方法或者执行查询。
说白了,虽然str是基本类型,是个正经的字符串,不像str2是个对象,但是当我们要调用 .length这种属性方法时,JS会自动将字符串转为字符串对象,然后调用相应的属性方法。当然,这不会改变str的数据类型,str依然是字符串。这一特性对于 Boolean 和Numbers 也同样如此(Symbol呢?这个有点特别,以后再说~)
不过总体而言如果不需要明确判断数据类型的时候,基本类型与基本类型包裹对象其实在用法上也没什么区别......那这些基本类型包裹对象有什么用呢?用处就是可以直接挂载自定义方法,我们继续操作~
对str与str2都直接新增自定义方法myAdd,然后调用。可以看出是字符串的str并没有挂载上方法,字符串对象str2却正常挂载上了方法,成功调用。所以说基本类型包裹对象可以直接挂载自定义方法,而基本类型不可以。
注意,这里不能和上文的自定义方法 String.prototype.myStr = function() { return 'My String!' } 混淆,上文是在构造函数prototype属性上新增自定义方法,不是直接在str和str2上新增方法。
三、基本类型与对象的区别
这篇文章写的很详细,我这里就不重复写了<JavaScript中基本数据类型和引用数据类型的区别>
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures
https://www.cnblogs.com/cxying93/p/6106469.html
https://www.cnblogs.com/ghost-xyx/p/4418750.html
https://blog.****.net/weixin_36182933/article/details/53995954