标识符Symbol和迭代器的实现
-
Symbol基础
Symbol("描述")
创建唯一标识符(每次调用返回新值)
Symbol.for("key")
全局注册表模式(相同key返回同一Symbol)
-
Symbol特性
- 作为对象属性键时:
obj[SymbolKey] = value
- 不参与常规遍历(不会出现在
Object.keys()
中) - 用于创建私有属性(外部无法通过
.
访问)
- 作为对象属性键时:
-
迭代器实现
[Symbol.iterator]() {let index = -1;const list = Object.values(this);return {next() {index++;return {done: index === list.length,value: list[index]};}}; }
- 使对象支持
for...of
遍历 - 通过
Object.values()
获取属性值数组 done
控制迭代终止条件
- 使对象支持
-
对象扩展
- 原生对象默认不可迭代(需手动添加迭代器)
for...of
本质调用对象的[Symbol.iterator]()
方法
-
代码示例
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title> </head><body><script>// Symbol 唯一标识符,打标记,不是用来存值// 它是值类型// Symbol,number,string,boolean,undefined,null// var a = null;// console.log(typeof a); //object ,历史遗留问题console.log(typeof Symbol()); //symbolvar s1 = Symbol("描述");console.log(s1) //Symbol(描述)var s2 = Symbol("描述");console.log(s1 == s2); //falsevar s3 = Symbol("age");const person = {id: 1001,name: "吴彦祖",gender: "女",[s3]: 20,};console.log(person.age); //undefinedconsole.log(person[s3]); //20// 使用ES6的Symbol.for方法在全局符号注册表中创建或获取一个共享的Symbol值var s1 = Symbol.for("age"); //1.创建var s2 = Symbol.for("age"); //2.读取缓存console.log(s1 == s2); //trueconst persona = {id: 1001,name: "吴彦祖",gender: "女",[Symbol.for("age")]: 20,};// 直接取,拿不到console.log(persona.age);//undefined// 遍历也拿不到for (let k of Object.keys(persona)) {console.log(k);}// 取console.log(persona[Symbol.for("age")]); //20//迭代器const personA = {id: 1001,name: "吴彦祖",gender: "女",[Symbol.iterator]() {let list = Object.values(this); //获取当前对象所有属性 [id,name,gender]let index = -1;return {next() {index++;return {done: index == list.length, //false无限循环,遇到true就结束循环value: list[index],};},};},};console.log("------自己给对象添加迭代器--------");//对象为啥不能被for.of遍历,答案是对象默认情况下没有迭代器(iterable)for (const k of personA) {console.log(k);}</script> </body></html>