JS数据类型 & 类型检测

141 阅读3分钟

JS的数据类型

基本类型

Undefined, Null, Boolean, Number, String, Symbol (ES6)

基本数据类型的值是按值访问的

  • 基本类型的值是不可变的
  • 基本类型的比较是它们的值的比较
  • 基本类型的变量是存放在栈内存里的。栈内存中包括了变量的标识符和变量的值。

引用类型

统称为Object类型。细分的话有Object, Function, Array, Date, RegExp,  

引用类型的值是按引用访问的。

  • 引用类型的值是可变的
  • 引用类型的比较是引用的比较
  • 引用类型的值是保存在堆内存中的对象。栈内存中保存了变量标识符和指向堆内存中该对象的指针,堆内存中保存了对象的内容。

Symbol

ES6引入了一种新的基本数据类型Symbol,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。

由于每一个Symbol的值都是不相等的,所以用Symbol作为对象的属性名,可以保证属性不重名。

Symbol作为对象属性名时不能用.运算符,要用方括号。

let sy = Symbol("key1");
let syObject = {};
syObject[sy] = "kk";
console.log(syObject); //{Symbol(key1): "kk"}

如果要读取到一个对象的Symbol属性,

使用Object.getOwnPropertySymbols() 获取所有Symbol属性

使用Reflect.ownKeys()获取所有属性包括Symbol

Object.getOwnPropertySymbols(syObject); // [Symbol(key1)]
Reflect.ownKeys(syObject); // [Symbol(key1)]

检测类型

typeof

检测一个变量是什么数据类型

  • 对于基本类型,除null以外,均可返回正确的结果
  • 对于引用类型,除function以外,一律返回object类型
  • 对于null,返回object类型
  • 对于function,返回function类型

instanceof

判断某个对象是不是另一个对象的实例。

A instanceof B  ,A的__proto__是否指向B的prototype,即A是否是B的实例。

function Parent(){};
function Child(){};
function Other(){};

Child.prototype = new Parent();
var child = new Child();

child instanceof Child; //true
child instanceof Parent; //true
child instanceof Object; //true
child instanceof Other; //false

Map 和 Object 的比较

Map

Object

意外的键

Map默认情况不包含任何键。只包含显式插入的键。

一个Object有一个原型,原型链上的键名有可能和你自己在对象上设置的键名产生冲突。

键的类型

一个Map的键可以是任意值,包括函数、对象或任意基本类型

一个Object的键必须是一个String或Symbol

键的顺序

Map中的key是有序的。因此,当迭代的时候,一个Map对象以插入的顺序返回键值。

除了字符串键和Symbol键,一个Object的键是无序的。

Size

Map的键值对 个数可以通过size属性获取

Object的键值对个数只能手动计算

迭代

Map是iterable的,可以直接被迭代

迭代一个Object需要以某种方式获取它的键然后才能迭代

性能

在频繁增删键值对的场景下表现更好

在频繁增删键值对的场景下未作出优化