重学JavaScript的数据类型

92 阅读3分钟

相信大家都知道是八大数据类型:undefined、null、boolean、number、string、object、symbolbigint,更相信大家很少甚至几乎没用过后两个。

一、两个冷门基本数据类型

  • symbol: 代表创建后独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的问题,比如你需要为某个对象添加元数据或标识符,但你无法确定这个对象上已有的属性名,这个时候可以用symbol
const user = { uniqueId: 'aaa', name: "zhangsan", age: 30 }; 
const uniqueId = Symbol("uniqueId"); 
user[uniqueId] = '001'; // 确保不会与其他属性名冲突
console.log(user); // {uniqueId: 'aaa', name: "zhangsan", age: 30,[Symbol(uniqueId)]: '001' }
  • bigintNumber 类型是基于 IEEE 754 双精度浮点数格式(64 位)实现的,因此它能表示的最大安全整数(Number.MAX_SAFE_INTEGER)为 9007199254740991,超过这个值的整数在操作时可能会出现精度问题,这个时候就需要用bigint
console.log(9007199254740991 + 1); // 输出: 9007199254740992
console.log(9007199254740991 + 2); // 输出: 9007199254740992,错误结果
const bigInt = BigInt("9007199254740992");
// 这里的 2n 表示一个值为 2 的 BigInt 类型数字
console.log(bigInt + 2n); // 输出 9007199254740994n,精确结果,

二、检测数据类型的方法

1、typeof

typeof能正确检测除null以外的所有基本数据类型,而数组、对象、null都会被判断为 object

2、instanceof

instanceof不能检测基本类型,但可以正确判断引用数据类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。

function myInstanceof(A, B) {
  A = A.__proto__;      // 获取对象 A 的原型
  B = B.prototype;      // 获取构造函数 B 的原型
  while (true) {
    if (A === B) return true; // 如果 A 的原型链中有与 B 的原型相同的原型,返回 true
    if (A === null) return false; // 如果 A 的原型链到达顶端null,返回 false
    A = A.__proto__; // 沿着原型链向上查找
  }
}

console.log(myInstanceof([], Array)); // true
console.log(myInstanceof([], Function)); // false

3、constrcutor

对象实例可以通过constrcutor访问它的构造函数

class Car {
  constructor(make, model) {
    this.make = make;
    this.model = model;
  }
}

const car = new Car('BYD', 'tang');
console.log(car.constructor === Car); // true
console.log(car.constructor === Object); // false

4、Object.prototype.toString.call()

Object.prototype.toString.call() 使用 Object 对象的原型方法toString 来判断数据类型。

console.log(Object.prototype.toString.call(42)); // 输出: "[object Number]" 
console.log(Object.prototype.toString.call('Hello')); // 输出: "[object String]"
console.log(Object.prototype.toString.call([])); // 输出: "[object Array]" 
console.log(Object.prototype.toString.call({})); // 输出: "[object Object]"

三、null 和 undefined 区别

undefined 代表的含义是未定义,null 代表的含义是空。一般变量声明了但还没有定义的时候会返回 undefinednull 主要用于赋值给一些可能会返回对象的变量,作为初始化。需要注意的,undefined不是保留字,是可以作为一个变量名的,需要通过void 0来获得一个安全的 undefined

  const undefined = "这是一个变量";
  console.log(void 0); // undefined
  console.log(undefined); // 这是一个变量

在解构赋值场景中,属性值为null时,默认值将不生效。

const obj = { name: "zhangsan", value: null }
const { age = 18, value = [] } = obj
const myValue = obj.value || []
console.log(age) // 18
console.log(value) // null
console.log(myValue) // []

四、包装类型

在调用基本类型的属性或方法时 JavaScript 会在后台隐式地将基本类型的值转换为对象,也可以使用 Object 函数显式地将基本类型转换为包装类型,用 valueOf 方法将包装类型倒转成基本类型。

const str = 'aaa'
console.log(str.length) // 3
console.log(Object(str)) // String{'aaa'}
console.log(Object(str).valueOf()) // aaa