Symbol的内置属性和方法

一、内置方法

  • asyncIterator:异步迭代器. (property)
  • iterator:迭代器。 (property)
  • for 创建Symbol()Symbol.for() 类似单例模式,首先会在全局搜索被登记的 Symbol 中是否有该字符串参数作为名称的 Symbol 值,如果有即返回该 Symbol 值,若没有则新建并返回一个以该字符串参数为名称的 Symbol 值,并登记在全局环境中供搜索。
  • keyFor Symbol.keyFor(sym) 方法用来获取全局 symbol 注册表中与某个 symbol 关联的键。
    语法
Symbol.keyFor(sym);  
  //参数
  // sym. (必选参数,需要查找键值的某个 Symbol 。)
  • hasInstance
  • isConcatSpreadable
  • match
  • matchAll
  • replace
  • split
  • search
  • species
  • toPrimitive
  • toStringTag
  • unscopables
  • useSetter
  • useSimple

二、API解析

1、异步迭代器(asyncIterator)

  • 定义:指定了一个对象的默认的异步迭代器,如果一个对象设置了这个属性,那么它就是异步可迭代对象,可用于for await…of 循环。
  • 给一个对象添加asyncIterator属性:
let as_iterator=new Obiect();
as_iterator[Symbol.asyncIterator]=async function* (){
    yield 'hello';
    yield 'waiting';
    yield 'ending';  
}
(async()=>{
      for await(let a of as_iterator){
              console.log(a); 
      }
}())

【注:】暂时没有设置了[Symbol.asyncIterator]这个属性的JavaScript对象
2、### 迭代器(iterator

  • 定义:
    为每一个对象定义了默认的迭代器,该迭代器可被【for...of】循环使用
  • 拥有迭代器属性对象
    • String
    • Map
    • Set
    • Array
    • arguments
    • Typed Arrays (类数组)
    • Generators
  • 自定义迭代器:
    1.利用generator函数:
    let my_iterator = {
  [Symbol.iterator] : function* () {
      yield 'hello';
      yield 'waiting';
      yield 'ending';
  }
}
console.log([...my_iterator]);  

2.数据结构默认的Iterator接口,可以通过for…of使用。解构赋值用的也是Iterator接口。

const other_interator={
    data:['hello',welcome,'world'],
    [Symbol.interator](){
      let ind=0;
      return {
        next:()=>ind<this.data.length?{value:this.data[ind++],done:false}:{value:undefined,}
        
}
  }
}
let abs = other_iterator[Symbol.iterator]()
console.log(abs.next());    //  {value: 'hello', one: false}
console.log(abs.next());    //  {value: 'welcome', one: false}
console.log(abs.next());    //  {value: 'world', one: false}
console.log(abs.next());  //  {value: undefined, done: true}

3、for
- 定义:不同的变量可以使用同一个Symbol值,Symbol.for()方法接收一个参数,然后查找是否有以该参数作为名称的Symbol值,如果有就返回这个Symbol值,否则就新建一个以该参数为名称的Symbol值。

let a = Symbol('symbol')
let b = Symbol('symbol')
console.log(a === b);   //  false

let symbol_a = Symbol.for('symbol');
let symbol_b = Symbol.for('symbol');
console.log(symbol_a === symbol_b); //  true

4、keyFor
定义:返回一个已使用的Symbol类型值的key,用来检测该参数作为名称的Symbol值是否已被使用

let a =Symbol.for('symbol');
let b=Symbol.for(a);
console.log(b)//symbol
console.log(a)//Symbol(symbol)
console.log(a===b) //false

5、hasInstance

  • 定义:当我们使用instanceof这个方法去检测对象A是不是对象B的实例的时候,实际上B就是调用的B[Symbol.hasInstance]这个方法
    • 常规使用
class Event {}
let e = new Event;
console.log(e instanceof Event);    //  true
console.log(Event[Symbol.hasInstance](e));  //true
  • 更改 [Symbol.hasInstance] 指向
class my_instance {
    static [Symbol.hasInstance](params) {
   return     typeof params   
    }
}
let a = new my_instance();
console.log(a instanceof my_instance);  // true
console.log(my_instance[Symbol.hasInstance](a));    // object

6、isConcatSpreadable

  • 定义:对象的Symbol.isConcatSpreadable属性等于一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。
let arr1 = ['c', 'd'];
['a', 'b'].concat(arr1, 'e') // ['a', 'b', 'c', 'd', 'e']
arr1[Symbol.isConcatSpreadable] // undefined

let arr2 = ['c', 'd'];
arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']

7、match

  • 定义:指定了匹配的是正则表达式,而不是字符串。String.prototype.match会调用此方法。
String.prototype.match(regexp)
// 等同于
regexp[Symbol.match](this)

class MyMatcher {
  [Symbol.match](string) {
    return 'hello world'.indexOf(string);
  }
}

'e'.match(new MyMatcher()) // 1

8、matcAll

  • ** 定义**:返回一个迭代器,该迭代器根据字符串生成正则表达式的匹配项??梢员籟String.prototype.matchAll] 调用
const re = /[0-9]+/g;
const str = '2016-01-02|2019-03-07';
const result = re[Symbol.matchAll](str);

console.log(Array.from(result, x => x[0]));
// expected output: Array ["2016", "01", "02", "2019", "03", "07"]

9、replace

  • 定义:对象的Symbol.replace属性,指向一个方法,当该对象被String.prototype.replace方法调用时,会返回该方法的返回值。
String.prototype.replace(searchValue, replaceValue)
// 等同于
searchValue[Symbol.replace](this, replaceValue)

下面这个例子

const x = {};
x[Symbol.replace] = (...s) => console.log(s);

'Hello'.replace(x, 'World') // ["Hello", "World"]

Symbol.replace方法会收到两个参数,第一个参数是replace方法正在作用的对象,上面例子是Hello,第二个参数是替换后的值,上面例子是World。

10、split

  • 定义:指向一个正则表达式的索引处分隔字符串的方法。此方法通过【 String.prototype.split() 】调用。
    其也是正则原型上的一个方法,在字符串使用split方法的时候会调用改方法。
class MySplitter {
  constructor(value) {
    this.value = value;
  }
  [Symbol.split](string) {
    let index = string.indexOf(this.value);
    if (index === -1) {
      return string;
    }
    return [
      string.substr(0, index),
      string.substr(index + this.value.length)
    ];
  }
}

'foobar'.split(new MySplitter('foo'))
// ['', 'bar']

'foobar'.split(new MySplitter('bar'))
// ['foo', '']

'foobar'.split(new MySplitter('baz'))
// 'foobar'

上面方法使用Symbol.split方法,重新定义了字符串对象的split方法的行为,

11、search

  • 定义:指定了一个搜索方法,该方法接受一个正则表达式,该方法返回的是字符串中匹配到正则表达式的索引。此方法通过【String.prototype.search()】来调用。
    1、正常使用:
    let publicStr = 'anfdsvka fahF KJ'
    let s= publicStr.search(/\a/g)
    console.log(s);   // 0

2、更改正则原型上的此方法

RegExp.prototype[Symbol.search] = () => {
  return -1;
}
console.log(s); // -1

12、species

  • 定义:对象的Symbol.species属性,指向一个构造函数。创建衍生对象时,会使用该属性。
class MyArray extends Array {
  static get [Symbol.species]() { return Array; }
}

const a = new MyArray();
const b = a.map(x => x);

b instanceof MyArray // false
b instanceof Array // true

总之,Symbol.species的作用在于,实例对象在运行过程中,需要再次调用自身的构造函数时,会调用该属性指定的构造函数。它主要的用途是,有些类库是在基类的基础上修改的,那么子类使用继承的方法时,作者可能希望返回基类的实例,而不是子类的实例。

13、 toPrimitive

  • 定义:是一个内置的Symbol值,它是作为对象的
let obj = {
  [Symbol.toPrimitive](hint) {
    switch (hint) {
      case 'number':
        return 123;
      case 'string':
        return 'str';
      case 'default':
        return 'default';
      default:
        throw new Error();
     }
   }
};

2 * obj // 246
3 + obj // '3default'
obj == 'default' // true
String(obj) // 'str'

14、toStringTag

  • 定义:对象的Symbol.toStringTag属性,指向一个方法。在该对象上面调用Object.prototype.toString方法时,如果这个属性存在,它的返回值会出现在toString方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制[object Object]或[object Array]中object后面的那个字符串。
({[Symbol.toStringTag]: 'Foo'}.toString())
// "[object Foo]"

// 例二
class Collection {
  get [Symbol.toStringTag]() {
    return 'xxx';
  }
}
let x = new Collection();
Object.prototype.toString.call(x) // "[object xxx]"

15、unscopables

  • 定义: 指用于指定对象值,其对象自身和继承的从关联对象的 with 环境绑定中排除的属性名称。
const publicObj = {
    a: '123',
    b: '234',
    c: undefined
}
publicObj[Symbol.unscopables] = {
    a: true,
    b: false
}

with(publicObj) {
    console.log(a); //  Uncaught ReferenceError: a is not defined
    console.log(b); //  '234'
    console.log(c); //  undefined
}

三、总结

1、asyncIterator 暂时无设置有该属性的JS对象;
2、iterator 迭代器,是在开发中可能会经常涉及到的一个Symbol属性,拥有该属性的数据类型包含:String、Array、arguments、Set、Map等;
3、hasInstance 在使用instanceof方法检测数据类型的时候,会优先调用此方法;
4、正则对象的原型上的方法包含:match、matcAll、replace、split、search
5、toStringTag 在使用 Object.prototype.toString() 去检测数据类型的时候,会优先调用 Symbol.toStringTag 这个方法

?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容