你应该知道的Symbol

大家好,我是十七,今天来和大家探讨一下 es6 的 Symbol 到底是什么鬼。

首先说说产生的 背景,即以前 js 的缺陷。想必大家肯定有过这种经历,设置对象属性的时候,很容易忘记之前的属性,导致属性覆盖,尤其是写大型项目的时候,这种情况会出现致命的 bug,导致项目出现各种问题。所以,在 es6 中,官方为了解决这一弊病,提出了 Symol 。其实还有一个原因,官方希望通过 Symbol 提供一种机制,就是以symbol为属性名的对象, 可以很轻松实现属性私有化,这个在后面会有解释,大家耐心看。

那么Symbol到底是很么呢,我们可以理解为类似字符串,一般约定俗称”字符”。Symbol 是一个函数,每次 Symbol() ,它都会创建一个唯一的 symbol 值,这个值是唯一的,是不可重复的。话不多说,上代码:

let a = Symbol()
let b = Symbol()
a    //Symbol()
b    //Symbol()
a === b   //false

a instanceof Object //false
typeof a //symbol

指的注意的是,Symbol 不能通过 new 来调用,因为 Symbol 是一个基本数据类型,typeof a运算符的结果,表明变量 a 是 Symbol 数据类型,而不是对象之类的其他类型。

Symol() 可以传递一个参数,参数的作用主要是对该 Symbol 实例进行描述,便于区分。注意,Symbol 函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。

let a = Symbol('foo');
let b = Symbol('bar');

a // Symbol(foo)
b // Symbol(bar)

a.toString() // "Symbol(foo)"
b.toString() // "Symbol(bar)"

// 没有参数的情况
let s1 = Symbol();
let s2 = Symbol();

s1 === s2 // false

// 有参数的情况
let s1 = Symbol('foo');
let s2 = Symbol('foo');

s1 === s2 // false

上面代码中,和 是两个 Symbol 值。如果不加参数,它们在控制台的输出都是Symbol(),不利于区分。有了参数以后,就等于为它们加上了描述,输出的时候就能够分清,到底是哪一个值。

由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。具体写法,大家请看:

let sym = Symbol();

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

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

注意:因为symbol属性需要通过计算所得,所以需要用放在 [ ] 里面。

然后咱们来说说Symbol的使用。Symbol 除了会给对象唯一属性之外,它真正强大的地方在于可以很轻松的将对象的属性私有化,就是只可以内部调用,外部无法使用。大家请看:

function MySym() {
  let symFn = Symbol('fn')
  let symProp = Symbol('prop')
  this[symProp] = "symbolProp"
  this[symFn] = function () {
    console.log('this is symbol prop')
  }

  this.call = function () {
    console.log('this is normal prop')
  }
  this.use = function () {
    this[symFn]()
    console.log('---------------------')
    this.call()
  }
}
let s = new MySym() 
s.use()
          //this is symbol prop
          //---------------------
          // this is normal prop

s[symFn]()  // Uncaught ReferenceError: symFn is not defined
s[symProp]  // Uncaught ReferenceError: symProp is not defined

这样就可以很简单的实现内部属性私有化,提高程序的安全性。

今天的讨论就到这里了,欢迎大家浏览讨论,有不对的地方还请大家多多指教,谢谢大家!

猜你喜欢

转载自blog.csdn.net/zjk325698/article/details/112692665
今日推荐