JS 数据类型的种类、判断以及转换

716 阅读5分钟

数据类型的种类

  • 基本数据类型:Undefined、Null、Boolean、Number、String、Symbol ( es6 新增,表示独一无二的值 ) 和 BigInt ( es10 新增 )
  • 引用数据类型:Object ( Object本质上是由一组无序的键值对组成的 )。里面包含 function、Array、Date 等。JavaScript 不支持任何创建自定义类型的机制,而所有值最终都将是上述 8 种数据类型之一。

数据类型的存储方式

  • 原始数据类型:直接存储在栈 ( stack ) 中,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储。
  • 引用数据类型:同时存储在栈 ( stack ) 和堆 ( heap ) 中,占据空间大、大小不固定。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

数据类型的判断

typeof 返回数据类型的字符串表达

  • typeof 对于原始类型来说,除了 null 都可以显示正确的类型
  • typeof 对于对象来说,除了函数都会显示 object
  • 不能区别 null 与 object / object 与 array
  • 另外对于 null 来说,很多人会认为他是个对象类型,其实这是错误的。虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象,然而 null 表示为全零,所以将它错误的判断为 object 。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。
console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof Symbol('protein'))// symbol
console.log(typeof []);              // object     []数组的数据类型在 typeof 中被解释为 object
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object     null 的数据类型被 typeof 解释为 object

instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例的原型链上

  • instanceof 左为实例,右为构造函数。即判断左是不是右的实例对象。内部机制是通过原型链来判断的
  • instanceof 可以精准判断引用数据类型 Array,Function,Object,而基本数据类型不能被 instanceof 精准判断,因为它本身不是一个实例对象
console.log(2 instanceof Number);                    // false
console.log(new Number(2) instanceof Number)         // true
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false  
console.log(Symbol('protein') instanceof Symbol)     // false 不支持语法:"new Symbol()"
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true    
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);

constructor 构造函数

  • 如果我创建一个对象,更改它的原型,constructor 就会变得不可靠
console.log((2).constructor === Number);                // true
console.log((true).constructor === Boolean);            // true
console.log(('str').constructor === String);            // true
console.log(Symbol('protein').constructor === Symbol)   // true
console.log(([]).constructor === Array);                // true
console.log((function() {}).constructor === Function);  // true
console.log(({}).constructor === Object);               // true
console.log(new Date().constructor === Date)            // true
console.log(new RegExp().constructor === RegExp)        // true
console.log(new Error().constructor === Error)          // true
// 改变原型指向
function Fn(){};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true
console.log(f instanceof Fn)        // true
console.log(f instanceof Array)     // true

Object.prototype.toString.call()

  • 使用 Object 对象的原型方法 toString,使用 call 改变 this 指向
const a = Object.prototype.toString;
console.log(a.call(2));             // [object Number]
console.log(a.call(true));          // [object Boolean]
console.log(a.call('str'));         // [object String]
console.log(a.call(Symbol()))       // [object Symbol]
console.log(a.call([]));            // [object Array]
console.log(a.call(function(){}));  // [object Function]
console.log(a.call({}));            // [object Object]
console.log(a.call(undefined));     // [object Undefined]
console.log(a.call(null));          // [object Null]
console.log(a.call(new Date()))     // [object Date]
console.log(a.call(new Error()))    // [object Error]
console.log(a.call(new RegExp()))   // [object RegExp]

判断数据类型实例

  • Number --- !isNaN(parseFloat(arg))

数据类型的转换

Boolean 布尔值的转换

  • 转换为布尔值调用 Boolean() 方法
  • !!运算符可以将右侧的值强制转换为布尔值,这也是将值转换为布尔值的一种简单方法
  • 转 Boolean 除了 undefined,null,false,0,-0,NaN,‘ ’ 空字符串 其他的值都转为 true,包括所有的对象。
原始值 转换目标 结果
number Boolean 除了 0、-0、NaN 都为 true
string Boolean 除了空字符串 ' ' 都为 true
undefined、null Boolean false
引用类型 Boolean true
number string 6 => '6'
Boolean、函数、Symbol string 'true'
数组 string [1, 2] => '1, 2'
对象 string '[ object, Object ]'
string number '6' => 6, 'p' => NaN
数组 number [] => 0, [ '6' ] => 6, 其他都是 NaN
null number 0
非数组的引用类型 number NaN
Symbol number 抛错

数字和字符串的转换

  • 转换为数字调用 Number()、parseInt() 和 parseFloat() 方法
  • 转换为字符串调用 .toString() 或者 String() 方法

四则运算符

  • 加法 + 运算符的特点
    • 运算中其中一方为字符串,那么就会把另一方也转化成字符串
    • 如果一方不是字符串或者数字,那么会将他转化成数字或者字符串
console.log(1 + '1'); // 11
console.log(true + true); // 2
console.log(4 + [1, 2, 3]); // 41, 2, 3
console.log('a' + + 'b'); // aNaN 因为 + 'b' 为 NaN
  • 非加法运算符来说只要其中一方不是数字就会被转化成数字
console.log(2 * '1'); // 2
console.log(2 * []); // 0
console.log(2 * ['2']); // 4
console.log(2 * [1, 2]); // NaN

== 和 === 运算符

  • === 判断左右类型和值是不是都相等
  • == 如果左右类型相等,则进行大小的比较,如果左右类型不相等会进行类型转换
  • 判断是否在对比 null 和 undefined 如果是返回 true
  • 判断两者的类型是否为 string 和 number,如果是就会将 string 转为 number
1 == '1' => 1 == 1 // true
  • 判断一方是否为 boolean 如果是就会将其转换成 number 在进行判断
'1' == true => '1' == 1 => 1 == 1 // true
  • 判断一方是否为 object 另一方是否为 string、number、symbol 是的话就会把 object 转换成原始类型在进行判断
'1'== { name: 'protein' } => '1' == '[ object, object ]' // false
  • 实例:[] == ![]
[] == ![] => [] == false => [] == 0 => 0 == 0 // true

==和===的比较流程.png