再也不怕面试官问我 Symbol 是什么了

420 阅读4分钟

再也不怕面试官问我 Symbol 是什么了

各位可以关注我的公众号《人生代码》,每天一篇干货

基本数据类型

通常面试官问你,都会问你 js 的基本类型都有哪些,你可能会回答:

  • Number,
  • String,
  • Boolean,
  • Undefined,
  • Null。

你以为完了,结果面试真的完犊子了,其实还有一个就是在 ES6 中,还新增了一个叫做:

  • Symbol

什么意思呢?表示唯一,独一无二的值,最大的用法是用来定义对象的唯一属性名。

Symbol 的疑难点

特别需要注意的是:

  • Symbol 函数栈不能用 new 命令,因为他是基本类型,无法使用 new 操作
var s = new Symbol() // 报错
VM161:1 Uncaught TypeErrorSymbol is not a constructor
    at new Symbol (<anonymous>)
    at <anonymous>:1:9
  • 不能使用 JSON.parse,JSON.stringify 进行深拷贝
var Ken = Symbol('kk')
var obj = {nameKen}
var copy = JSON.parse(JSON.stringify(obj))
console.log(copy)// 你会发现 name 属性没了
  • 唯一性质
let Ken = Symbol("KK");
console.log(Ken);   // Symbol(KK)
typeof(Ken);        // "symbol"
 
// 相同参数 Symbol() 返回的值不相等
let Ken1 = Symbol("KK")
Ken === Ken1;       // false
  • 作为对象属性 key 时,在获取其值的时候,只能使用 [] 形式获取,不能使用 . 操作符
let Ken = {};
Ken[sy] = "kk";
 
Ken[sy];  // "kk"
Ken.sy;   // undefined
  • Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问

但是不会出现在 for...infor...of 的循环中,也不会被 Object.keys()Object.getOwnPropertyNames() 返回。如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols()Reflect.ownKeys() 取到。

let Ken = {};
Ken[sy] = "kk";
console.log(Ken);
 
for (let i in Ken) {
  console.log(i);
}    // 无输出
 
Object.keys(Ken);                     // []
Object.getOwnPropertySymbols(Ken);    // [Symbol(key1)]
Reflect.ownKeys(Ken);                 // [Symbol(key1)]
  • 定义常量

在 ES5 使用字符串表示常量。例如:

const COLOR_RED = "red";
const COLOR_YELLOW = "yellow";
const COLOR_BLUE = "blue";

但是用字符串不能保证常量是独特的,这样会引起一些问题:

const COLOR_RED = "red";
const COLOR_YELLOW = "yellow";
const COLOR_BLUE = "blue";
const MY_BLUE = "blue";
 
function ColorException(message) {
   this.message = message;
   this.name = "ColorException";
}
 
function getConstantName(color) {
    switch (color) {
        case COLOR_RED :
            return "COLOR_RED";
        case COLOR_YELLOW :
            return "COLOR_YELLOW ";
        case COLOR_BLUE:
            return "COLOR_BLUE";
        case MY_BLUE:
            return "MY_BLUE";         
        default:
            throw new ColorException("Can't find this color");
    }
}
 
try {
   
   var color = "green"// green 引发异常
   var colorName = getConstantName(color);
} catch (e) {
   var colorName = "unknown";
   console.log(e.message, e.name); // 传递异常对象到错误处理
}

但是使用 Symbol 定义常量,这样就可以保证这一组常量的值都不相等。用 Symbol 来修改上面的例子。

const COLOR_RED = Symbol("red");
const COLOR_YELLOW = Symbol("yellow");
const COLOR_BLUE = Symbol("blue");
 
function ColorException(message) {
   this.message = message;
   this.name = "ColorException";
}
function getConstantName(color) {
    switch (color) {
        case COLOR_RED :
            return "COLOR_RED";
        case COLOR_YELLOW :
            return "COLOR_YELLOW ";
        case COLOR_BLUE:
            return "COLOR_BLUE";
        default:
            throw new ColorException("Can't find this color");
    }
}
 
try {
   
   var color = "green"// green 引发异常
   var colorName = getConstantName(color);
} catch (e) {
   var colorName = "unknown";
   console.log(e.message, e.name); // 传递异常对象到错误处理
}