JavaScript基础篇-数据类型

159 阅读2分钟

前言

在我们学习编程的时候,最先接触的就是数据类型了,每一种语言都是自己的数据类型,JavaScript 也不例外,JavaScript 的数据类型主要包括两种大的类型 基本类型 和 引用类型,接下来我们就来分析一下这两种类型的区别。

数据类型

基本类型

  • Number 数字类型
  • String 字符串类型
  • Boolean 布尔类型
  • Null null 类型
  • undefined undefined 类型

引用类型

  • Object 对象类型

两种的区别

基本类型的存储是存储在 栈 中,而引用类型的存储是在 堆 中,基本变量存储的是具体的值,而引用类型存储的是 堆中的地址,如下图所示

1620049692(1).jpg

为什么基本类型与引用类型的存储方式不一致

  • 堆比栈大,栈比对速度快。
  • 基础数据类型比较稳定,而且相对来说占用的内存小。
  • 引用数据类型大小是动态的,而且是无限的。
  • 堆内存是无序存储,可以根据引用直接获取。

检测数据类型

检测类型的方法我们有 typeof、instanceof、Object.prototype.toString.call()等

  • typeof 可以看到 typeof 可以检测出大部分的数据类型,function 类型也可以检测出来,缺陷是 null 和 Array 类型都检测出来是 object 类型,Array 是引用类型,检测出来是 object 类型是没有问题的,但是 null 出是 object 类型就是一个 bug 了,而且这个 bug 已经在 JavaScript 中存在很久了
   console.log(typeof 2)    // number
   console.log(typeof '2')  // string
   console.log(typeof true) // boolean
   console.log(typeof undefined) // undefined
   console.log(typeof null) // object
   console.log(typeof function() {})   // function
   console.log(typeof [])   // object
   console.log(typeof {})   // object
  • instanceof instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,缺陷是无法判断它的构造函数具体是哪个,可以使用 实例.proto.constructor === 构造函数 进行判断
class People {}
class Student extends People {}
let s = new Student
console.log(s instanceof Student)   // true
console.log(s instanceof People)   // true
console.log(s instanceof Object)   // true
  • Object.prototype.toString.call() 原理是使用 Object.prototype 上的原生 toString() 方法判断数据类型
// Boolean 类型,tag 为 "Boolean"
Object.prototype.toString.call(true);            // => "[object Boolean]"
// Number 类型,tag 为 "Number"
Object.prototype.toString.call(1);               // => "[object Boolean]"
// String 类型,tag 为 "String"
Object.prototype.toString.call("");              // => "[object String]"
// Array 类型,tag 为 "String"
Object.prototype.toString.call([]);              // => "[object Array]"
// Arguments 类型,tag 为 "Arguments"
Object.prototype.toString.call((function() {
  return arguments;
})());                                           // => "[object Arguments]"
// Function 类型, tag 为 "Function"
Object.prototype.toString.call(function(){});    // => "[object Function]"
// Error 类型(包含子类型),tag 为 "Error"
Object.prototype.toString.call(new Error());     // => "[object Error]"
// RegExp 类型,tag 为 "RegExp"
Object.prototype.toString.call(/\d+/);           // => "[object RegExp]"
// Date 类型,tag 为 "Date"
Object.prototype.toString.call(new Date());      // => "[object Date]"
// 其他类型,tag 为 "Object"
Object.prototype.toString.call(new class {});    // => "[object Object]"

后续

  • 引用变量赋值时会有两个赋值方式 浅拷贝和深拷贝
  • ES5 的时候有六种数据类型主要有 Object、Number、String、Boolean、Null、undefined
  • ES6 ES7 的时候又在 ES5 的基础上新增了 SymbolBigInt