面试题:说说你对Symbol的理解

2,632 阅读3分钟

一、是什么

SymbolES6 新推出的一种基本类型,它表示独一无二的值

它可以选择接受一个字符串作为参数或者不传,但是相同参数的两个Symbol 值不相等

//不传参数
const s1 = Symbol();
const s2 = Symbol();
console.log(s1 === s2); // false

// 传入参数
const s3 = Symbol('debug');
const s4 = Symbol('debug');
console.log(s3 === s4); // false

可以通过typeof判断是否为Symbol类型

console.log(typeof s1); // symbol

不是一个完整的构造函数,不能通过new Symbol() 来创建

const s1 = new Symbol();
// Uncaught TypeError: Symbol is not a constructor

二、方法与属性

Symbol有两个方法,如下:

  • Symbol.for()
  • Symbol.keyFor()

Symbol.for()

用于将描述相同的Symbol变量指向同一个Symbol

let a1 = Symbol.for('a');
let a2 = Symbol.for('a');
a1 === a2  // true
typeof a1  // "symbol"
typeof a2  // "symbol"

let a3= Symbol("a");
a1 === a3      // false

它跟symbol()的区别是Symbol()定义的值每次都是新建,即使描述相同值也不相等

Symbol.for()定义的值会先检查给定的描述是否已经存在,如果不存在才会新建一个值,否则描述相同则他们就是同一个值

Symbol.keyFor()

Symbol.keyFor()是用来检测该字符串参数作为名称的 Symbol 值是否已被登记,返回一个已登记的 Symbol 类型值的 key

let a1 = Symbol.for("a");
Symbol.keyFor(a1);    // "a"

let a2 = Symbol("a");
Symbol.keyFor(a2);    // undefined

Symbol只有一个属性:

  • description

description

用来返回Symbol数据的描述

// Symbol()定义的数据
let a = Symbol("acc");
a.description  // "acc"
Symbol.keyFor(a);  // undefined

// Symbol.for()定义的数据
let a1 = Symbol.for("acc");
a1.description  // "acc"
Symbol.keyFor(a1);  // "acc"

// 未指定描述的数据
let a2 = Symbol();
a2.description  // undefined

description能返回所有Symbol类型数据的描述,而Symbol.keyFor()只能返回Symbol.for()在全局注册过的描述

三、使用场景

借助symbol独一无二的特性,我们可将symbol应用在:

  • 对象添加属性
  • 作为私有属性

对象添加属性

在对象上添加属性的时候,避免出现相同属性名,产生某一个属性被改写或覆盖的情况

let n = Symbol('N');
let obj = {
    name: "前端收割机",
    age: 11,
    [n]: 100
}; 

使用symbol作为对象属性的时候,需要注意两点:

  • 需要通过方括号的形式访问symbol属性
const sym3 = Symbol('test');

const obj = {
    [sym3]: 'foo'
}

obj[sym3];       //"foo"
  • 迭代属性的时候,某些情况不能得到该symbol属性,如for...infor...of....

私有属性

ES6 中的类是没有 private 关键字来声明类的私有方法和私有变量的,我们可以利用 Symbol 的唯一性来模拟

const speak = Symbol();
class Person {
    [speak]() {
        console.log(123)
    }
}
let person = new Person()
console.log(person[speak]())

使用者无法在外部创建出一个相同的 speak,所以就无法调用该方法

四、结束语

如果觉得这篇文章对你有帮助,可以伸出你的小手,为这篇文章点个赞

我是前端路上一位新晋的萌新,怀着学习的态度,怀着认识各位同伴的心态,把自己的知识分享出来,除了让自己对知识认知更加巩固,也希望大家能够通过我写的文章学到一点微薄的知识,如果知识内容有误,可以在评论区或者下面公众号告诉我,我会立刻更改

最后,我也创建了一个 【前端收割机】的公众号,希望大家可以关注一波,里面的文章都是掉头发之作