目录

JS内置对象3分钟掌握Symbol

JS—内置对象:3分钟掌握Symbol

个人博客: 。感谢关注

1. 目录

2. 内置对象

常用的内置对象,只是简单的说一下,最想说的还是Symbol,面试问道的频率高。比方说:

//Object	所有对象的基类,提供属性/方法如 create(), keys(), assign()
//Function	函数构造器,所有函数实例的原型对象
//Array	数组对象,提供 push(), map(), filter() 等方法
const obj = new Object();
const arr = new Array(1, 2, 3);

//Math用于进行常见的数学运算
Math.random()//用于生成一个随机数,
Math.floor()//用于向下取整,
Math.sqrt()//用于开平方等。

//Date用于处理日期和时间
new Date()//可以创建一个表示当前日期和时间的对象

//String用于处理字符串
charAt()//用于获取特定位置的字符,
concat()//用于连接两个或多个字符串,
indexOf()//用于查找特定字符串的位置等。

//Map	ES6 键值对集合,支持任意类型键
//Set	ES6 唯一值集合
//WeakMap	键为弱引用的 Map,防止内存泄漏
//WeakSet	值为弱引用的 Set
const map = new Map();
map.set("key", "value");
const set = new Set([1, 2, 3]);

//Error	通用错误基类,如 new Error("message")
//TypeError	类型错误(如调用不存在的方法)
//SyntaxError	语法错误(如 JSON 解析失败)
//ReferenceError	引用错误(如访问未声明变量)
try {
  throw new TypeError("类型错误");
} catch (e) {
  console.error(e);
}
//JSON	JSON 解析工具,提供 parse(), stringify()
const json = JSON.stringify({ name: "Alice" });

//RegExp	正则表达式对象,如 new RegExp("\\d+", "g")
//Promise	ES6 异步操作对象,支持链式调用 .then()/.catch()
//Proxy	ES6 代理对象,用于拦截对象操作(如 get/set)
//Reflect	ES6 反射工具,提供对象操作的静态方法
const regex = new RegExp("\\d+", "g");
const promise = new Promise((resolve) => resolve("OK"));

3. Symbol

Symbol是ES6中引入的基本数据类型。用来创建 唯一的不可变 的值。通常用于对象属性的key。

唯一性

每个symbol的值都是唯一的,即使他们的描述也相同,如下

let sym1 = Symbol("name");
let sym2 = Symbol("name");
console.log(sym1 === sym2); // false

https://i-blog.csdnimg.cn/direct/8fb13839d2b247a399c850b3035346e5.png

不可变

Symbol 一旦创建,无法修改其值或描述

// 创建带描述的 Symbol
const sym = Symbol("original description");
console.log(sym.description); // "original description"
// 尝试修改描述
sym.description = "new description"; // 静默失败,无报错但无效
console.log(sym.description); // 仍输出 "original description"
// 甚至尝试强制修改(严格模式会报错)
Object.defineProperty(sym, 'description', { value: "hacked" }); // 抛出 TypeError

https://i-blog.csdnimg.cn/direct/fcf40aec25924080b623490c718d19b0.png

非字符串键

作用于对象时,symbol的键不会隐式的转为字符串,避免命名冲突。

//键是Symbol("id")这个对象。并不是字符串
const obj = {
  [Symbol("id")]: 123  // 唯一的键
};

不可枚举性

symbol属性默认不会出现在for…in、Object.keys() 或 JSON.stringify() 中

//定义obj1,其中定义了两个属性,一个普通属性,一个symbol属性
let obj1 = {name:"zhangsan",[Symbol('id')]:"001"}
JSON.stringify(obj1) //{"name":"zhangsan"}
Object.keys(obj1)//['name']

https://i-blog.csdnimg.cn/direct/327c5ceadfc242dbaad6c21851898f5f.png

4. Symbol的常见用法与问题

常见获取symbol的方法

//创建
const symId1 = Symbol("id")
//通过全局注册表去获取Symbol
const symId2 = Symbol.for("id")
const symId3 = Symbol.for("id")
console.log(symId1 === symId2) //false
console.log(symId2 === symId3) //true
//前面都说了唯一性了,为啥这里会打印true呢?
//因为,你通过Symbol.for方式去获取symbol对象,原理是它优先从全局注册表中查找以key为描述的symbol对象
//如果没有查找到就创建一个symbol对象返回,如果查找到了,就把查找到的symbol对象返回。

https://i-blog.csdnimg.cn/direct/a6639d671ca543c5bc0108603f819695.png

常见用法

  1. ​避免属性名冲突。解决对象属性名可能被覆盖的问题:
const user = {
  id: 1,
  name: "Alice",
  [Symbol("internal_id")]: "X-123" // 隐藏的内部属性
};
  1. 定义类的私有成员。模拟私有属性(通过闭包和 Symbol):
const _counter = Symbol("counter");
class MyClass {
  constructor() {
    this[_counter] = 0; // "私有"属性
  }
  increment() {
    this[_counter]++;
  }
}
  1. 定义常量。确保常量的唯一性:
const LOG_LEVEL = {
  DEBUG: Symbol("debug"),
  INFO: Symbol("info"),
  ERROR: Symbol("error")
};

常见问题

  1. for…in,Object.keys方法无法获取到symbol,那么,要怎么获取symbol呢?
const obj = {
  [Symbol("id")]: 123,
  name: "Alice"
};
obj[Symbol("sex")] = "男"
//获取symbol对象
Object.getOwnPropertySymbols(obj);//[Symbol(id), Symbol(sex)]
//获取所有的key
Reflect.ownKeys(obj)//['name', Symbol(id), Symbol(sex)]

https://i-blog.csdnimg.cn/direct/040b22c621484c0f96a87d68b4ebc2ff.png

  1. Symbol.iterator 的作用

当一个对象实现了Symbol.iterator迭代器,则该对象可以用for…of遍历。比方说我们的内置对象Array

const arr = [10, 20, 30];
const iterator = arr[Symbol.iterator](); // 获取迭代器
console.log(iterator.next()); // { value: 10, done: false }
console.log(iterator.next()); // { value: 20, done: false }
console.log(iterator.next()); // { value: 30, done: false }
console.log(iterator.next()); // { done: true }

https://i-blog.csdnimg.cn/direct/7a3149325d464908afcce6429d4c7be4.png

https://i-blog.csdnimg.cn/direct/5e6adbaa8d4b44e69f7997b9715be2ed.png

  1. for…in和for…of
let arr1 = ["1","2",Symbol("id"),"3"]
for (const key in arr1) {
//这里输出0,1,2,3
//然后通过key去获取值。
 console.log(key); 
}

let arr1 = ["1","2",Symbol("id"),"3"]
for (const value of arr1) {
//这里输出值
 console.log(value); 
}

https://i-blog.csdnimg.cn/direct/e1a42be6cf314c5c8ac1015861a27d27.png

for…in 是 JavaScript 中用于遍历对象 可枚举的字符串键属性 的语法,其底层机制如下:

a. ​遍历范围

​自身属性:对象直接定义的属性。

​继承属性:从原型链继承的可枚举属性。

b. ​遍历规则

​仅遍历字符串键:for…in ​只处理属性名为字符串的键,忽略 Symbol 键。

​可枚举性检查:仅遍历 enumerable: true 的属性(通过 Object.defineProperty 或直接赋值定义的属性默认可枚举)

let obj = {}
obj.name = "zhangsan"
obj[Symbol("sex")] = "男"
let func = ()=>{
}
obj[func] = "李四"
//这里方法之所以能遍历,是因为这里的方法被存储为了字符串
//再回过头去看前面说的  非字符串键
Object.keys(obj)  //['name', '()=>{\n}']

https://i-blog.csdnimg.cn/direct/f600e83feb49420ebec3c884d6d41c97.png