js知识版图-数据类型

一、js中内存分为栈内存、堆内存此处引申知识点:js中堆栈内存及函数处理机制

栈内存
  • 从数据类型角度思考 栈内存 存储基本数据类型的值、引用类型的指针、函数存储位置信息。
  1. 提供一个供js代码自上而下执行的环境(代码都是在栈中执行的)。
  2. 由于基本数据类型值比较简单,他们都是直接在栈内存中开辟一个位置,把值直接存储进去,当栈内存被销毁,存储的那些基本值也都跟着销毁了。
    此处引申知识点:作用域(全局、函数、块级)
堆内存
  • 从数据类型角度思考 堆内存 存储引用类型的值、函数的代码块。
  1. 存储引用类型的值(对象:键值对 函数:代码字符串)。
  2. 当前堆内存释放销毁,那么这个引用值彻底没了。
  3. 堆内存的释放:当堆内存没有被任何的变量或者其它东西所占用,浏览器会在空闲的时候,自主的进行内存回收,把所有不被占用的堆内存销毁掉。
  4. xxx = null 通过空对象指针null可以让原始变量(或者其他东西)谁都不指向,那么原有被占用的堆内存就没有被东西占用了,浏览器会销毁它。
    此处引申知识点:引用类型的赋值、浅拷贝、深拷贝

js中数据类型

  • 基本数据类型:number、string、boolean、null、undefined、symbol、bigint (栈内存)
  • 引用数据类型:Object、Array、Date、Function、Regexp (堆内存)
数据类型检测方法

1. typeof

  • 对于基本类型,除null以外,均可以返回正确的结果。
  • 对于引用类型,除function以外,一律返回object类型。
  • 对于null,返回object类型。
  • 对于function,返回function类型。
typeof ''             // 'string'
typeof 123            // 'number'
typeof Symbol()       // 'symbol'
typeof true           // 'boolean'
typeof undefined      // 'undefined'
typeof new Function() // 'function'
typeof null           // 'object'
typeof []             // 'object'
typeof new Date()     // 'object'
typeof new RegExp()   // 'object'
typeof new Error()    // 'object'
typeof document       // 'object'
typeof window         // 'object'

比较适合检测基本数据类型,在一些源码中使用示例:

line37:https://github.com/vuejs/vue/blob/dev/dist/vue.js#L14-L379
/**
 * Check if value is primitive.
 */
function isPrimitive(value) {
  return (
    typeof value === "string" ||
    typeof value === "number" ||
    // $flow-disable-line
    typeof value === "symbol" ||
    typeof value === "boolean"
  );
}

2. instanceof

instanceof 是用来判断A是否为B的实例,表达式为:A instanceof B,如果A是B的实例,则返回true,否则返回false。instanceof检测的是原型,通过原型链来判断。 instanceof 只能用来判断两个对象是否属于实例关系,而不能判断一个对象实例具体属于哪种类型。
此处引申知识点:js原型、原型链

    instanceof(A, B) = {
      let a = A.__proto__
      let b = B.prototype
      if (a === b) {
          return true
      }
      return false
    }
function Person() {}
let man = new Person()

man instanceof Person // true
man instanceof Object // true
let test = new String('message')

console.log(test instanceof String)  // true
console.log(test instanceof Object)  // true

let test = 'message'

console.log(test instanceof String)  // false
console.log(test instanceof Object)  // false

Array.isArray()鉴别数组的最好方法

3. constructor

构造函数: function Person()
构造函数的原型: Person.Protptype,此原型上有一个constructor构造属性指向构造函数 Person,Person.Protptype.constructor === Person
实例对象: let man = new Person(),此时Person.Protptype.constructor传递到man上,man.constructor === Person
此处引申知识点:js原型、实例对象

function Person() {}
let man = new Person()

console.log(Person.prototype.constructor === Person) // true
console.log(man.constructor === Person) // true
'xixin'.constructor === String           // true
new Number(123).constructor === Number   // true
true.constructor === Boolean             // true
Symbol().constructor === Symbol          // true
new Function().constructor === Function  // true
new Error().constructor === Error        // true
new Date().constructor === Date          // true
[].constructor === Array                 // true
document.constructor === HTMLDocument    // true
window.constructor === Window            // true
  • null 和 undefined 是无效的对象,因此是不会有constructor存在的,这两种类型的数据类型需要通过其他方式来判断。
  • 函数的constructor是不稳定的,这个主要体现在自定义对象上,当开发者重写prototype后,原有的constructor引用会丢失。
function Root () {
  this.name = '小程'
  this.arr = [1,2,3]
}
function Person() {}
Person.prototype = new Root()
let man = new Person()
console.log(man.constructor)
console.log(man.constructor === Root)  // true
function Person() {}
Person.prototype = {
  name: '小程',
  arr: [1,2,3]
}
let man = new Person()
console.log(man.constructor)
console.log(man.constructor === Object)  // true

4. Object.prototype.toString.call()

toString() 方法返回一个表示该对象的字符串,每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。

let obj = new Object()
obj.toString() // 返回 [object, object]

备注: 如 ECMAScript 5 和随后的 Errata 中所定义,从 JavaScript 1.8.5 开始,toString() 调用 null 返回[object Null]undefined 返回 [object Undefined]

(Object.prototype.toString.call(value).slice(8, -1)) // 获取到类型值
(Object.prototype.toString.call('123').slice(8, -1)) => // 'String'

let toString = Object.prototype.toString

toString.call('')  // [Object String]
toString.call(1)  // [Object Number]
toString.call(true)  // [Object Boolean]
toString.call(Symbol)  // [Object Symbol]
toString.call(new Function())  // [Object Function]
toString.call(new Date())  // [Object Date]
toString.call([])  // [Object Array]
toString.call(new RegExp())  // [Object RegExp]
toString.call(new Error())  // [Object Error]
toString.call(document)  // [Object HTMLDocument]
toString.call(window)  // [Object Window] 浏览器环境
toString.call(window)  // [object global] node环境


// since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

你可能感兴趣的:(js知识版图-数据类型)