javascript-不常见的数据类型

这里是一些js中不常见的数据类型

Symbol

可以创建一个唯一的值

new Symbol();
// Uncaught TypeError: Symbol is not a constructor
const symbol1 = Symbol("lucas");
const symbol2 = Symbol("lucas");
symbol1 !== symbol2; // true

js 运行过程会设置一个全局 Symbol 注册表,可以通过Symbol.for(key)检索指定 key 的 Symbol 值

使用场景

  • 定义常量(枚举)
  • 对象私有属性。需要注意的是:遍历对象的时候,该属性不会出现在 for...infor...of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回,可以用 Object.getOwnPropertySymbols() 获取
  • 实现一个可遍历的对象
const obj = {
  from: 0,
  to: 10,
  [Symbol.iterator]: function () {
    return {
      current: this.from,
      last: this.to,
      next() {
        if (this.current <= this.last) {
          return { done: false, value: this.current++ };
        } else {
          return { done: true };
        }
      },
    };
  },
};

for (let num of obj) {
  console.log(num);
}
  • 其他内置 Symbol
    • Symbol.match
    • Symbol.toPrimitive

BigInt

可以用任意精度表示整数,并且可以正确执行整数运算而不会溢出。同为 BigInt 类型的变量才能做运算,并且 BigInt 永远不会等于 Number

new BigInt(5);
// Uncaught TypeError: BigInt is not a constructor
5n === BigInt(5);

const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);
// 9007199254740991n
const maxPlusOne = previousMaxSafe + 1n;
// 9007199254740992n

BigInt(1.5);
// RangeError
BigInt("1.5");
// SyntaxError

// 注意这里的类型转换
typeof 1n === "bigint"; // true
typeof BigInt("1") === "bigint"; // true

但要注意运算符有使用局限,比如不能用单目运算符、不能使用无符号右移等,详见 BigInt-MDN

Map

Map 跟普通对象的区别是不限键类型,并且是有序的

  • new Map()
  • map.set(key, value)
  • map.get(key)
  • map.has(key)
  • map.delete(key)
  • map.clear()
  • map.size
const map = new Map();
map.set("1", "lucas");
map.set(1, "gogogo");
console.log(map.get(1)); // 'gogogo'
console.log(map.get("1")); // 'lucas'
console.log(map.size); // 2
const obj = { name: "lucas" };
map.set(obj, "gogogo");

将对象转换成 Map 对象

const prices = new Map([
  ["banana", 1],
  ["orange", 2],
  ["meat", 10],
]);

使用 Object.fromEntries 将 Map 对象转换成一个普通对象

const prices = Object.fromEntries([
  ["banana", 1],
  ["orange", 2],
  ["meat", 10],
]);
// prices: { banana: 1, orange: 2, meat: 10 }

遍历 Map 对象可以用 map.keys()/map.values()/map.entrie()

Set

Set 跟普通数组的区别主要在于唯一,并且没有下标的概念

  • new Set(iterable)
  • set.add(value)。返回 Set 对象本身
  • set.delete(value)。删除值,如果 value 在这个方法调用的时候存在则返回 true ,否则返回 false
  • set.has(value)
  • set.clear()
  • set.size
let set = new Set();
let a = { name: "a" };
let b = { name: "b" };
let c = { name: "c" };
set.add(a);
set.add(b);
set.add(c);
set.add(a);
set.add(b);
alert(set.size); // 3

可以使用 for..offorEach 来遍历 Set。除此之外,也可以用 set.keys()/set.values()/set.entrie() 实现遍历

let set = new Set(["oranges", "apples", "bananas"]);
set.forEach((value, valueAgain, set) => {
  // 这里的三个参数,前两者是一样的。注意下标是数组特有的东西
  console.log(value, valueAgain);
});

WeakMap

WeakMap 只能接受对象作为键,并保持了对键名所引用的对象的弱引用,在没有其他引用和该键引用同一对象,这个对象将会被垃圾回收(相应的 key 则变成无效的)

WeakSet

WeakSet 只能接受对象作为值,并且储存的对象都是被弱引用的,如果没有其他的变量或属性引用这个对象值,则这个对象将会被垃圾回收掉(不考虑该对象还存在于 WeakSet 中)

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值