Symbol类型

Symbol 是ES6引入的一种新的原始数据类型,由于Symbol是一个原始类型的值,不是对象,不能添加属性.基本上
是一种类似于字符串的数据类型

概述

Symbol 可以接受一个字符串作为参数,主要是为了容易区分
Symbol 函数的参数只是对当前Symbol的描述,相同参数的Symbol返回值是不相同的
Symbol 值不能与其他类型的值进行运算(字符串的加运算)
Symbol 可以转字符串,布尔值
var sys =Symbol() // Symbol()
sys.toString() // "Symbol()"
Boolean(sys) //true
!sys //false

作为属性名的Symbol

由于每一个Symbol都是不相同的 意味Symbol值可以作为标识符用于对象的属性名,保证不会出现同名的属性
var mySymbol = Symbol()
1.
var a ={}
a[mySymbol]='hello'
2.
var a ={[mySymbol]:'hello'}
3.
var a = {}
object.defineProperty(a,mySymbol,{value:'hello'})
* Symbol值作为属性名的时候,不能使用点选运算符,因为点运算符后面总是字符串,所以实际的属性名是一个字符串
而不是Symbol值.同理,Symbol值在对象里的时候必须放在[]符号内
eg1:
const COLOR_RED =Symbol()
const COLOR_GREEN =Symbol()
function tes1t(color){
switch(color){
    case COLOR_RED:
    return COLOR_GREEN;
    case COLOR_RED:
    return COLOR_GREEN;
    default:
    throw new Error('undefined color')
 }
}
eg2:
const obj={
DEBUGGER:Symbol('debugger')
}

魔术字符串

魔术字符串是指在代码中多次出现、与代码形成强耦合的某一个具体字符串或者数值

var shapeType={triangle:'triangle'}
function getArea(shape,options){
	var area=0
	switch(shape){
	case shapeType.triangle:
	area=1*options.height*options.width
	break
	}
	return area
}
var shapeType={triangle:Symbol()}
function getArea(shape,options){
	var area=0
	switch(shape){
	case shapeType.triangle:
	area=1*options.height*options.width
	break
	}
	return area
}
getArea(shapeType.triangle,{width:10,height:20}) //200
shapeType.triangle //Symbol()

Symbol.for,Symbol.keyFor()

Symbol.for

1.Symbol()[未登记的Symbol值]和Symbol.for()都会生成新的Symbol,区别在于前者会被登记在全局环境中供搜索
2.Symbol.for()不会每次调用都返回一个新的Symbol值,而是会在全局先检查给定的key是否已经
存在,如果不存在就新建一个,如果存在会返回同一个Symbol值
var s1 = Symbol('cat')
var s2 = Symbol('cat')
s1==s2  //false
var s1 = Symbol.for('cat')
var s2 = Symbol.for('cat')
s1==s2  //true

symbol.keyFor()

Symbol.keyFor() 方法返回一个已经登记的Symbol类型的key值
var s1 =Symbol.for('cat')
Symbol.keyFor(s1)  //'cat'
var s1 =Symbol('cat')
Symbol.keyFor(s1) //undefined
var test = Symbol()
var test2=Symbol()
test1==test //false
// 使用Symbol.for(),可以重新使用一个Symbol值
var test1 = Symbol.for()
var test2 = Symbol.for()
test1===test2 //true
* Symbol.for 为Symbol值登记名字是全局环境的,可以在不同的iframe或service worker中获取
iframe = document.creatElement('iframe')
iframe.src = String(window.location)
document.body.appendChild(iframe)
iframe.contentWindow.Symbol.for('foo') ==Symbol.for('foo')  //true

属性名的遍历

Object.getOwnPropertyNames()只能返回Symbol类型的键名 Reflect.ownkeys可以返回所有类型的键名

Symbol作为属性名的时候不会出现在for...in for...of循环中,也不会出现在Object.keys,Object.getOwnPropertyNames
返回,会被Object.getOwnPropertySymbols获取指定对象的所有用作属性名的Symbol值
var obj ={}
var a = Symbol('a')
var b = Symbol('b')
var objProperty  = Object.getOwnPropertySymbols(obj)
obj // {Symbol(a): "hello", Symbol(b): "world"}
ObjProperty // [Symbol(a), Symbol(b)]
let obj ={}
let obj ={[Symbol('key')]:1,enum:2,nonEnum:3}
Reflect.ownKeys(obj) //["enum", "nonEnum", Symbol(key)]
以Symbol值作为名称的属性不会被常规遍历方法获得,可以利用这个特性,为独享定义一些私有但又只希望
内部使用的方法
var size = Symbol('size') 
        class Collection{
            constructor(){
                this[size]=0
            }
            add(item){
                this[this[size]]=item
                this[size]++
            }
            static sizeOf(instance){
                return instance[size]

            }
        }
        var x = new Collection() //Collection {Symbol(size): 0}
        Collection.sizeOf(x) //0
        x.add('foo')  // Collection {0: "foo", Symbol(size): 1}
        Collection.sizeOf(x) //1
        Object.keys(x) // ['0']
        Object.getOwnPropertyNames(x) //['1']
        Object.getOwnPropertySymbols(x) //[Symbol(size)]

内置的Symbol值

Symbol.hasInstance

对象的Symbol.hasInstance属性指向内部一个方法,对象使用instanceOf运算符时会调用这个方法,判断对象是否是
某个构造函数的实例eg. foo instanceof Foo 在语言内部实际调用的是Foo[Symbol.hasInstance](foo)

Symbol.isConcatSpreadable

对象的Symbol.isConcatSpreadable属性等于一个布尔值,表示该对象使用Array.property.concat()时是否可以展开
   let Arr1 = [1,2,3]
      let Arr2 = [3,4]
      var Arr3 = Arr1.concat(Arr2) //[1, 2, 3, 3, 2]
      let Arr4 = [5,6]
      Arr4[Symbol.isConcatSpreadable]= false
      let Arr5 = Arr1.concat(Arr4) //[1, 2, 3, Array(2)]

Symbol.species

对象的Symbol.species属性指向一个方法对象创造实例的时候会调用this.constructor[Symbol.species]存在
就会使用这个属性作为构造函数来创建新的实例对象
Symbol,species属性默认的读取器如下
static get [Symbol.species](){
  return this
}

Symbol.match

对象的Symbol.match属性指向一个函数,当执行str.match(myObject)时,如果改属性存在,会调用它返回该方法的返回值
String.property.macth(regexp)===>regexp[Symbol.macth](this)

Symbol.replace

对象的replace属性指向一个方法,当String.property.replace方法调用时会返回该方法的返回值
String.property.replace(searchValue,replaceValue) ==> searchValue[Symbol.replace](this,replaceValue)

Symbol.search

对象的Symbol.search属性指向一个方法,当对象被String.property.search方法调用时会返回该方法的返回值
String,property.search(regexp) ==> regexp[Symbol.search](this)

Symbol.split

对象的Symbol.split属性指向一个方法,当对象被String.property.split方法调用时会返回该方法的返回值
String,property.search(separator,limit) ==> regexp[Symbol.search](this,limit)

Symbol.iterator

对象的Symbol.split属性指向其默认的遍历器方法,即对象在进行for...of循环时调用这个方法,返回该对象的默认遍历器

Symbol.toPrimitive

对象的Symbol.toPrimitive属性指向一个方法,对象被转为原始类型的时候会调用这个方法,返回该对象对应的原始值
posted @ 2021-05-16 11:58  文件传输助手01  阅读(244)  评论(0编辑  收藏  举报