数据类型
基本数据类型
- Number
- String
- Boolean
- undefined
- null
- Symbol(ES2015)
-
引用数据类型
Object
- Array
- Function
Date,Math,Set,Map,WeakSet,WeakMap,WeakRef
区别
基本数据类型的数据称为原始值,即最简单的数据。原始值保存在栈(Stack)中,按值(by value)访问。其占据内存空间是固定的,更适合放在空间较小的栈中,查询速度较快。
引用数据类型的数据称为引用值,是由多个值构成的对象。引用值散乱地保存在堆(Heap)中,按引用(by reference)访问,因此当作为参数传递时,实际上是传递了引用值所在的内存地址。在堆中可占据的内存空间较大且灵活,但查询速度较慢。

类型判断
typeof
用法:typeof instance | typeof(instance)
typeof 返回数据类型
对于基本数据类型及Function类型,
typeof将返回正确的数据类型typeof 'str'; // string;typeof 1; // numbertypeof true; // booleantypeof undefined; // undefinedtypeof Symbol(); // symboltypeof BigInt(123); // biginttypeof Function(); // function
除Function之外的引用数据类型,通过
new生成的实例,特殊数据结构,typeof将返回object```javascript typeof new String(); typeof new Date(); typeof Math; // js内置Math对象 typeof new Map(); typeof new Set(); typeof new WeakMap(); typeof new WeakSet();
// object
- 对于`null` 返回 `object`> 在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"```bashtypeof null === 'object'; // true
instanceof
通过原型链的 prototype 检测对象是否是构造函数的实例,返回一个布尔值
const str = new String();const date = new Date();const weakmap = new WeakMap();function Person(name) { this.name = name };const man = new Person();str instanceof String; // truedate instanceof Date; // trueweakmap instanceof WeakMap; // trueman instanceof Person; // true
instanceof 将通过原型链的 prototype 向上查询,因此派生类的实例对于基类也将返回 true
// 接上述例子date instanceof Object; // trueman instanceof Object; // trueMath instanceof Object; // true
同时需要注意的是,若 prototype 指向的值被修改,返回结果也将发生变化,但应避免这种情况发生
Object.prototype.toString()
toString() 是对象内置方法,对于对象将返回 [Object type],因此可以借用 Function.prototype.call() 或 Function.prototype.apply() 方法,使实例通过 Object.prototype.toString() 获取类型
对于基本数据类型,调用**toString()**时实际上是通过包装类创建一个实例调用方法返回结果,再销毁实例
原始值被当作构造函数创建的一个对象来使用时,JavaScript会将其转换为一个对象,以便可以使用对象的特性,而后抛弃对象性质,并将它变回原始值
出自《JavaScript启示录》
Object.prototype.toString.call(date); // [object Date]Object.prototype.toString.call(man); // [object Object]Object.prototype.toString.call(Math); // [object Math]
因此可以封装一个方法获取数据类型
function _typeof(data) {return Object.prototype.toString.call(data).slice(8, -1).toLowerCase();}
Array.isArray()
判断是否是数组
Array.isArray([]); // trueArray.isArray('str'); // false
类型转换
在JavaScript中,只有三种类型转换,分别是:
- 转换成
number类型 - 转换成
string类型 - 转换成
boolean类型强制转换
强制转换主要是使用三种基本数据类型的包装类即Number()、String()、Boolean(),除此之外转换成number类型还可使用parseInt()、parseFloat()Number()
引用红宝书中的具体规则如下:
主要难点在于对象的转换规则:
我们结合下具体例子加以理解: ```javascript const obj = { a: 1 }; const arr = []; const obj1 = { valueOf() { return {} }, toString() { return {} } };if (typeof obj.valueOf() === 'object') {Number(obj.toString());} else {Number(obj.valueOf());}
Number(obj); // NaN Number(arr); // 0 Number(obj1); // Uncaught TypeError: Cannot convert object to primitive value
- `obj.valueOf()` 为对象,调用`toString()`获取字符串`[object Object]`,转换结果为`NaN`- `arr.valueOf()` 为数组对象,调用`toString()`获取空字符串,转换结果为 `0`- 我们将 `obj1` 的`valueOf()`、`toString()` 返回值都设为对象,此时 `Number()` 执行转换将报错此外,对于字符串转换为数值,还可以使用`parseInt()`、`parseFloat()`<br />两者用法相似,但有些区别:- `parseInt()` 会取整,`parseFloat()` 不会- `parseInt()` 可以传入第二个参数指明转换进制,`parseFloat()` 则不支持```javascript// parseInt 与 Number 主要区别Number(1.3); // 1.3parseInt(1.3); // 1Number('123aa'); // NaNparseInt('123aa'); // 123Number(true); // 1parseInt(true); // NaNNumber(null); // 0parseInt(null); // NaNNumber(undefined); // NaNparseInt(undefined); // NaNNumber([]); // 0parseInt([]); // NaNNumber({}); // NaNparseInt({}); // NaN
String()
- 对于
number类型,转换成相应的字符串 null、undefined、true、false转换成相应的字符串- 字符串不变
- 对象,调用
toString(),对原始类型按上述规则转换;如果是对象,则调用valueOf(),对原始类型同上,若valueOf()返回对象,则报错。
针对对象的转换规则,和Number()相似,只是互换了toString()、valueOf()方法
if (typeof obj.toString() === 'object') {String(obj.valueOf());} else {String(obj.toString());}
const obj = { a: 1 };const arr = [];const obj1 = {valueOf() { return {} },toString() { return {} }};String(obj); // [object Object]String(arr); // ''String(obj1); // Uncaught TypeError: Cannot convert object to primitive value
Boolean()
布尔值转换规则较为简单,仅下面几种情况转换结果为 false
- false
- 空字符串
- 0、NaN
- null
- undefined
== 、 ===、Object.is()
== 相等运算符
在比较左边两边时仅对比值是否相同,且涉及类型转换,其规则如下:
null与undefined相等- 两边都为
number类型直接对比值大小 - 一方为
string/boolean,一方为number,将string/boolean转换成number,再进行比较 - 只有一方为对象,则调用
valueOf()获取原始值,再根据上述规则进行 - 两边都为对象,则判断两边对象引用地址是否相等
=== 严格相等运算符
左右两边不仅值要想等,其类型也必须一致,但是对于 NaN 类型,将返回false
NaN === NaN; // false
Object.is()就是在 === 基础上正确返回对 NaN 类型的判断, 同时还有 +0 和 -0 不想等
Object.is(NaN, NaN); // trueObject.is(+0, -0); // false
