ES6 简单数据类型Symbol(待深入)

我先发个测试类吧,也有一些注释,如果有有问题的地方请指出,有看不懂的可以一起探讨

然后,我也多去看看,多去整理下symbol类型在实际应用时的应用场景。

/**
 * 测试symbol.asyncIterator
 * 这个符号表示异步迭代器API函数
 */
export function symbolAsyncIterator () {
  class Foo {
    constructor (max) {
      this.max = max
      this.asyncIdx = 0
    }
    // yield* 是表达式,用于委托给另一个generator 或可迭代对象。
    // 测试next()
    * nextTT () {
      while (this.asyncIdx < this.max) {
        yield this.asyncIdx
        this.asyncIdx++
      }
    }

    async * [Symbol.asyncIterator] () {
      while (this.asyncIdx < this.max) {
        yield new Promise((resolve) => {
          resolve(this.asyncIdx++)
        })
      }
    }
  }
  async function asyncCount () {
    let f = new Foo(5)
    for (let index = 0; index < 5; index++) {
      console.log(f.nextTT().next())
    }
    for await (const x of f) {
      console.log(x)
    }
  }
  asyncCount()
}
/**
 * 有一些问题,在new 子类的时候报错TypeError: Cannot call a class as a function
 * 该方法决定一个构造器对象是否认可一个对象是它的实例。Symbol.hasInstance
 */
export function symbolHasInstance () {
  class Fooc {}
  class FoocSun extends Fooc {
    [Symbol.hasInstance] () {
      return false
    }
  }
  // let f = new Foo()
  let fs = new FoocSun()
  // console.log(Symbol.hasInstance(f))
  console.log(fs)
  console.log(Fooc[Symbol.hasInstance](fs))
}
/**
 * Symbol.isConcatSpreadable为false或假值或默认值会导致整个对象被追加到数组末尾
 * Symbol.isConcatSpreadable为true或真值会导致这个数组元素被打平到数组实例
 * 打平:就相当于将数组内部元素提取出来
 * Symbol.isConcatSpreadable默认值为undifined,默认值时等同于false
 */
export function symbolIsConcatSpreadable () {
  // 数组降维
  let a = [1, 2, 3]
  let b = [4, [5, 6], 7]
  b.forEach((element, index) => {
    a = a.concat(b[index])
  })
  console.log(a)
  // IsConcatSpreadable
  console.log(b[Symbol.isConcatSpreadable])
  console.log(a.concat(b))
  b[Symbol.isConcatSpreadable] = false
  console.log(a.concat(b))
  b[Symbol.isConcatSpreadable] = true
  console.log(a.concat(b))
}
/**
 * 迭代器,类似于asyncIterator(异步迭代器),
 */
export function symbolIterator () {
  class Foo {
    constructor (max) {
      this.max = max
      this.idx = 0
    }
    * [Symbol.iterator] () {
      while (this.idx < this.max) {
        yield this.idx++
      }
    }
  }
  function acount () {
    let f = new Foo(5)
    for (const x of f) {
      console.log(x)
    }
  }
  acount()
}
/**
 * 通过使用参数,改变原有正则匹配字符串
 */
export function symbolMatch () {
  console.log('foobar'.match(/ob/))
  class FooMatch {
    constructor (str) {
      this.str = str
    }
    [Symbol.match] (target) {
      return target.includes(this.str)
    }
  }
  console.log('foobar'.match(new FooMatch('ob')))
  console.log('bazobar'.match(new FooMatch('ob')))
}
/**
 * 重定义替换规则
 */
export function symbolReplace () {
  class FooReplace {
    constructor (str) {
      this.str = str
    }
    [Symbol.replace] (target, replaceVal) {
      console.log(target.split(this.str))
      return target.split(this.str).join(replaceVal)
    }
  }
  let fr = new FooReplace('foo')
  console.log('barfoobaz'.replace(fr, 'qxx'))
}
/**
 * 重定义search规则
 */
export function symbolSearch () {
  class FooSearch {
    constructor (str) {
      this.str = str
    }
    [Symbol.search] (target) {
      return target.indexOf(this.str)
    }
  }
  let fr = new FooSearch('foo')
  console.log('barfoobaz'.search(fr))
  console.log('foobaz'.search(fr))
}

/**
 * 定义:一个函数值,该函数作为创建派生对象的构造函数
 * 通过定义静态的获取器(getter),可以覆盖新创建实例的原型定义
 */
export function symbolSpecies () {
  class Bar extends Array {}
  class Baz extends Array {
    static get [Symbol.species] () {
      return Array
    }
  }

  let bar = new Bar()
  console.log(bar instanceof Array)
  console.log(bar instanceof Bar)
  bar = bar.concat('bar')
  console.log(bar)
  console.log(bar instanceof Array)
  console.log(bar instanceof Bar)
  let baz = new Baz()
  console.log(baz instanceof Array)
  console.log(baz instanceof Baz)
  baz = baz.concat('baz')
  console.log(baz)
  console.log(baz instanceof Array)
  console.log(baz instanceof Baz)
}
/**
 * 定义:一个正则表达式方法,该方法在匹配正则表达式的索引位置拆分字符串。由String.prototype.split()方法使用
 */
export function symbolSplit () {
  class StringSplit {
    constructor (str) {
      this.str = str
    }
    [Symbol.split] (target) {
      return target.split(this.str)
    }
  }
  let ss = new StringSplit('abc')
  console.log('12abc33'.split(ss))
}
/**
 * 定义:一个方法,该方法将对象转换为相应的原始值(基本数据类型值)。由ToPrimitive抽象操作使用
 * 函数参数(hint)值仅为number,string,default
 */
export function symbolToPrimitive () {
  // 一个没有提供 Symbol.toPrimitive 属性的对象,参与运算时的输出结果
  var obj1 = {}
  console.log(+obj1) // NaN
  console.log(`${obj1}`) // "[object Object]"
  console.log(obj1 + '') // "[object Object]"

  // 接下面声明一个对象,手动赋予了 Symbol.toPrimitive 属性,再来查看输出结果
  var obj2 = {
    [Symbol.toPrimitive] (hint) {
      console.log('hint=', hint)
      if (hint === 'number') {
        return 10
      }
      if (hint === 'string') {
        return 'hello'
      }
      return true
    }
  }
  console.log(Number(obj2)) // 10      -- hint 参数值是 "number"
  console.log(`${obj2}`) // "hello" -- hint 参数值是 "string"
  console.log(obj2 + 'q') // "true"  -- hint 参数值是 "default"
}
/**
 * 定义:一个字符串,该字符串用于创建对象的默认字符串描述。由内置方法Object.prototype.toString()使用
 */
export function symbolToStringTag () {
  class Bar {
    constructor () {
      this[Symbol.toStringTag] = 'Bar'
    }
  }
  let bar = new Bar()
  console.log(bar.toString())
  console.log(bar[Symbol.toStringTag])
}
/**
 * 鉴于严格模式下禁止使用with,因此不推荐使用该内置符号。不做深入研究
 * 定义:一个对象,该对象所有的以及继承的属性,都会从关联对象的with环境绑定中排除
 */
export function symbolUnsopables () {
  'use script'
  let o = { foo: 'bar' }
  // with(o){
  //   console.log(foo)
  // }
  o[Symbol.unscopables] = {
    foo: true
  }
// with(o){
//   console.log(foo)
// }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值