【前端面试小册-】第2节,复习Symbol

373 阅读4分钟

1、Symbol使用场景

1.1、唯一性

在 Es5对象属性名都是字符串,属性名出现重复时,后者会覆盖前者;

而每个从Symbol()返回的symbol值都是唯一的,可保证对象的每个属性名的唯一性,可解决属性名的冲突问题

// symbol不会被覆盖
const s1 = Symbol('test');
const s2 = Symbol('test');

let obj = {
    [s1]: "知识星球:前端职场圈",
    [s2]: "公众号:前端面试资源"
}
console.log(obj)  // { [Symbol(test)]: '知识星球:前端职场圈', [Symbol(test)]: '公众号:前端面试资源' }

// ES5 会被覆盖
const s1 = 'test';
const s2 = 'test';

let obj = {
    [s1]: "知识星球:前端职场圈",
    [s2]: "公众号:前端面试资源"
}

console.log(obj)  // { test: '公众号:前端面试资源' }

1.2、私有属性

1、symbol不会出现在 Object.keys()的结果中,但是可以用 Object.getOwnPropertySymbols() 函数获取,

function getObj() {
    const s1 = Symbol('公众号:前端面试资源');
    const obj = {};
    obj[s1] = '公众号:前端面试资源';
    return obj;
  }
  
  const obj = getObj();
  
  Object.keys(obj); // []
  
  // 除非有这个 s1 的引用,否则无法访问该属性
  obj[Symbol('公众号:前端面试资源')]; // undefined
  
  // 用 getOwnPropertySymbols() 依然可以拿到 symbol 的引用
  const [symbol] = Object.getOwnPropertySymbols(obj);
  obj[symbol]; // '公众号:前端面试资源'
  

2、JSON.stringify()会忽略symbol属性名和属性值

const s1 = Symbol('知识星球: 前端职场圈');
const s2 = Symbol('公众号: 前端面试资源');
const obj = { 
    [s1]: '知识星球: 前端职场圈', 
    [s2]: '公众号: 前端面试资源', 
    test1: s1 ,
    test2: s2
};

let res = JSON.stringify(obj); 
console.log(res);// "{}"

2、Symbol使用方式

const s1 = Symbol();
const s2 = Symbol();

s1 === s2; // false

const obj = {};
obj[s1] = '知识星球';
obj[s2] = '前端职场圈';

obj[s1]; // '知识星球'
obj[s2]; // '前端职场圈'

console.log(typeof s1); //symbol

3、Symbol特点唯一性

const s1 = Symbol('前端职场圈');
const s2 = Symbol('前端职场圈');

s1 === s2; // false
console.log(s1); // 'Symbol(前端职场圈)'

4、Symbol注册中心

Symbo有一个全局的symbol注册中心,用Symbol.for()创建的symbol会添加到这个注册中心,并用它的 description作为索引键。如果你用Symbol.for()创建带有相同 description的两个 symbol,它们就是相等的

Symbol.for()方法接受一个字符串,然后全局搜索有没有以该参数作为描述值的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局

4.1、Symbol.for

const s1 = Symbol.for('前端职场圈');
const s2 = Symbol.for('前端职场圈');

s1 === s2; // true
console.log(s1); // 'Symbol(前端职场圈)'

4.2、Symbol.keyFor

Symbol.keyFor()方法返回一个已全局注册的 Symbol 类型值的描述值,如果该 Symbol 类型值未全局注册,则返回undefined

let s1 = Symbol.for("前端职场圈")
let s2 = Symbol("前端职场圈")
Symbol.keyFor(s1) // 前端职场圈
Symbol.keyFor(s2) // undefined

Symbol.for才会全局注册,所以s1能获取到;Symbol生成的不会全局注册,所以Symbol.keyFor(s2) 为 undefined

5、Symbol使用场景

5.1、唯一性

在 Es5对象属性名都是字符串,属性名出现重复时,后者会覆盖前者;

而每个从Symbol()返回的symbol值都是唯一的,可保证对象的每个属性名的唯一性,可解决属性名的冲突问题

// symbol不会被覆盖
const s1 = Symbol('test');
const s2 = Symbol('test');

let obj = {
    [s1]: "知识星球:前端职场圈",
    [s2]: "公众号:前端面试资源"
}
console.log(obj)  // { [Symbol(test)]: '知识星球:前端职场圈', [Symbol(test)]: '公众号:前端面试资源' }

// ES5 会被覆盖
const s1 = 'test';
const s2 = 'test';

let obj = {
    [s1]: "知识星球:前端职场圈",
    [s2]: "公众号:前端面试资源"
}

console.log(obj)  // { test: '公众号:前端面试资源' }

5.3、私有属性

1、symbol不会出现在 Object.keys()的结果中,但是可以用 Object.getOwnPropertySymbols() 函数获取,

function getObj() {
    const s1 = Symbol('公众号:前端面试资源');
    const obj = {};
    obj[s1] = '公众号:前端面试资源';
    return obj;
  }
  
  const obj = getObj();
  
  Object.keys(obj); // []
  
  // 除非有这个 s1 的引用,否则无法访问该属性
  obj[Symbol('公众号:前端面试资源')]; // undefined
  
  // 用 getOwnPropertySymbols() 依然可以拿到 symbol 的引用
  const [symbol] = Object.getOwnPropertySymbols(obj);
  obj[symbol]; // '公众号:前端面试资源'
  

2、JSON.stringify()会忽略symbol属性名和属性值

const s1 = Symbol('知识星球: 前端职场圈');
const s2 = Symbol('公众号: 前端面试资源');
const obj = { 
    [s1]: '知识星球: 前端职场圈', 
    [s2]: '公众号: 前端面试资源', 
    test1: s1 ,
    test2: s2
};

let res = JSON.stringify(obj); 
console.log(res);// "{}"

6、文末彩蛋

文章:首发地址

想要一起组队学习小册全部内容的,可以评论区留言。