ES6 新数据类型 symbol

  • 预热

javascript有 6种 数据类型

  1. undefined
  2. null
  3. 布尔值(Boolean)
  4. 字符串(String)
  5. 数值(Number)
  6. 对象(Object)

而 symbol 为ES6新增的数据类型。表示独一无二的值,使用Symbol()定义(S大写!)

  • 理解symbol

那么这个symbol到底是个什么东西,我们看下面例子:

const a = Symbol()
const b = Symbol()
console.log(a==b) // false

在我理解,就是对a、b进行随机赋值,并且永远不会重复

再来一个例子

const b = Symbol();
let a = {};
a[b] = 'red';
console.log(a[b]); // red
console.log(a) // {Symbol(): "red"}
a = {
    [b]: 'blue',
    b: 'black'
}
console.log(a); // {b: "black", Symbol(): "blue"}
a.b = 'yellow'
console.log(a); //{b: "yellow", Symbol(): "blue"}
a[b] = 'black'
console.log(a); //{b: "yellow", Symbol(): "black"}
a['b'] = 'white'
console.log(a); // {b: "white", Symbol(): "black"}

我们可以看到,如果用Symbol()生成的symbol在对象中显示的是Symbol()而不对定义的b,
而需要对symbol值进行修改则需要使用a[b];通过这里我们可以看到symbol的一个使用好处就是不会被不经意的a.b修改了值

  • symbol使用
  1. 写法
let mySymbol = Symbol();

// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';

// 第二种写法
let a = {
  [mySymbol]: 'Hello!'
};

// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });

// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
  1. 添加描述
const sym = Symbol('name');
console.log(sym); // Symbol(name)

定义在Symbol()内添加描述
ES2019 提供方法descripttion

const sym = Symbol('name');
console.log(sym.description); // name
  1. 赋值
let mySymbol = Symbol();

// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';

// 第二种写法
let a = {
  [mySymbol]: 'Hello!'
};

// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });

// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
  1. 遍历

Symbol 作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。但是,它也不是私有属性,有一个Object.getOwnPropertySymbols方法,可以获取指定对象的所有 Symbol 属性名
《ECMAscript 6入门》 ——阮一峰

如果要遍历symbol则需要使用 Object.getOwnPropertySymbols 方法

const a = Symbol('a')
const b = Symbol('b')
const symList = {
    [a]: 1,
    [b]: 2
}
console.log(Object.getOwnPropertySymbols(symList)); // [Symbol(a), Symbol(b)]

Object.getOwnPropertyNames方法得不到Symbol属性名;

不过,另一个新的 API,Reflect.ownKeys方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。

  1. Symbol.for(),Symbol.keyFor()
    一开始我们说过symbol的概念,symbol为唯一的;但是我们非要使用相同的symbol值呢;
    这时候我们就得用 Symbol.for()
const a = Symbol.for('c')
const b = Symbol.for('c')
console.log(a == b); // true
console.log(a); // Symbol(c)

获取Symbol.for()定义的描述可以通过 Symbol.keyFor() 来获取,但是如果是通过Symbol()写的描述就获取不到了

const a = Symbol.for("c");
console.log(Symbol.keyFor(a)); // c
const b = Symbol("c");
console.log(Symbol.keyFor(b)); // undefined
  1. 代码中使用/使用场景
    比如我们要进行判断,而判值提前定义为常量
const a = 'NAME_A'
const b = 'NAME_B'
const c = 'NAME_C'
function Func(val) {
    switch (val) {
        case a:
            return 1
        case b:
            return 2
        case c:
            return 3
        default:
            return -1
    }
}
console.log(Func(a)); // 1

这里我们并不关心obj里对象值是什么此时我们使用Symbol()

const a = Symbol('a')
const b = Symbol('b')
const c = Symbol('c')
function Func(val) {
    switch (val) {
        case a:
            return 1
        case b:
            return 2
        case c:
            return 3
        default:
            return -1
    }
}
console.log(Func(a)); // 1

that all

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.概述 ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象...
    赵然228阅读 828评论 2 10
  • 概述 ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加...
    oWSQo阅读 553评论 1 3
  • 1.概述 ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对...
    DC_er阅读 328评论 0 0
  • 概述 ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添...
    米诺zuo阅读 356评论 0 0
  • 属性的简洁表示法 ES6允许直接写入变量和函数,作为对象的属性和方法。 上面代码表明,ES6允许在对象之中,直接写...
    oWSQo阅读 532评论 0 0