乐趣区

关于javascript:js-数据类型总结

一. js 数据类型

  • String
  • Number
  • Boolean
  • null
  • Undefined
  • Object(包含 js 派生类:Array, Function, Set, Map, Date, RegExp, WeakMap, WeakSet)
  • Symbol
  • BigInt(ES2020, 用来示意大于 js 中最大整数 2^53 – 1 的整数)

分为根本类型(除 Obejct 类型外的类型)和援用类型(复合类型,Object 类型)

  1. 根本数据类型:值类型, 变量存储在栈内存中
  2. 援用数据类型:变量存储在堆内存和栈内存中,栈内存中 存储变量的标识符和 指向堆内存中该对象的指针即 堆内存中该对象的地址 ),援用类型的值是 按援用拜访

undefined 与 null 区别以及应用场景

null 指代空对象指针
应用场景:(1)开释内存(2)空值判断

undefined 示意此处应该有一个值,然而还没有定义
应用场景:(1)变量被申明了,但没有赋值时,就等于 undefined。(2)调用函数时,应该提供的参数没有提供,该参数等于 undefined。(3)对象没有赋值的属性,该属性的值为 undefined。(4)函数没有返回值时或者 return 前面什么也没有,返回 undefined

初始化变量时可依据心愿寄存类型指定
let a = null;  // 寄存对象
let b = undefined;   // 寄存数值

symbol 类型

symbol 用于模仿公有办法或属性,任意一个 symbol 数据是一个举世无双的值

symbol 属性名以及对象各类属性的属性名遍历:let obj = Object.create({}, {
  getFoo: {value: function() {return this.a;},
    enumerable: false,
  }
})
obj.a = 1,
obj.b = function() {},
obj[Symbol('a')] = 2,

Object.getOwnPropertySymbols(obj); //[Symbol(a)]  遍历本身 symbol 类型属性
Object.getOwnPropertyNames(obj); //['a', 'b', 'getFoo']  遍历本身非 symbol 类型属性(包含不可枚举属性)Reflect.ownKeys(obj);  //[Symbol(a), 'a', 'b', 'getFoo']  遍历本身所有类型属性,包含不可枚举和 symbol 类型
Object.keys(obj); //['a', 'b'] 遍历本身可枚举属性,// for...in 遍历可枚举属性(包含继承而来的), 搭配 hasOwnProperty 应用过滤出本身可枚举属性

二. 数据类型的判断形式

  • typeof
  • instanceof
  • constructor
  • Object.prototype.toString.call()
  1. typeof
    判断后果: ‘string’、’number’、’boolean’、’undefined’、’function’、’symbol’、’bigInt’、’object’

非凡情景

// 数据类型与 typeof 后果表现形式不同:console.log(typeof function(){});  // 'function'
console.log(typeof null);          // 'object'

// 对于 null, Object 及其派生类型(Array, Date, RegExp 等),无奈应用 typeof 进行类型的判断,须要应用 instanceof
console.log(typeof new Date());    // 'object'
console.log(typeof new RegExp());  // 'object'
  1. instanceof

语法:A instanceof B , 即判断 A 是否为 B 类型的实例,也能够了解为 B 的 prototype 是否在 A 的原型链上

console.log([] instanceof Array);                  // true
console.log({a: 1} instanceof Object);             // true
console.log(new Date() instanceof Date);           // true

// 留神:对于根本类型,应用字面量申明的形式能够正确判断类型
console.log(new String('dafdsf') instanceof String) // true
console.log('csafcdf' instanceof String) // false, 原型链不存在
  1. constructor

当一个函数 F 被定义时,JS 引擎会为 F 增加 prototype 原型,而后在 prototype 上增加一个 constructor 属性,并让其指向 F 的援用,F 利用原型对象的 constructor 属性援用了本身,当 F 作为构造函数创建对象时,原型上的 constructor 属性被遗传到了新创建的对象上,从原型链角度讲,构造函数 F 就是新对象的类型。这样做的意义是,让对象诞生当前,就具备可追溯的数据类型

console.log([].constructor === Array)                // true
console.log(new Date().constructor === Date)         // true
console.log(new RegExp().constructor === RegExp)     // true

// 非凡的, null 和 undefined 无奈应用这种形式判断,因为他们不是通过构造函数形式申明

在 js 中,个别会应用批改原型的形式实现 js 的继承,这种状况下个别要同步批改 constructor 属性, 避免援用的时候出错, 例如:

function Aoo(){}
function Foo(){} 
Foo.prototype = new Aoo();
Foo.prototype.constructor = Foo;
var foo = new Foo(); 
console.log(foo instanceof Foo)//true 
console.log(foo instanceof Aoo)//true
  1. Object.prototype.toString.call()
console.log(Object.prototype.toString.call(1))          // '[object Number]'
console.log(Object.prototype.toString.call(1n))         // '[object BigInt]'
console.log(Object.prototype.toString.call('123'))      // '[object String]'
console.log(Object.prototype.toString.call(null))       // '[object Null]'
console.log(Object.prototype.toString({}))         // '[object Object]'
console.log(Object.prototype.toString.call([]))         // '[object Array]'
console.log(Object.prototype.toString.call(function a() {}))  // '[object Function]'

综上可得,最能精确判断数据类型的形式为 Object.prototype.toString.call()

特地的,理论我的项目开发中,常常用于判断对象和数组的几种形式:

  • instanceof
  • isPrototypeOf: Array.isPrototypeOf({} | []), 基于原型链的概念
  • constructor: [] | {}.constructor = Array
  • isArray
  • Object.prototype.toString.call({} | [])
退出移动版