JavaScript中原始数据类型Symbol如何使用(javascript,symbol,开发技术)

时间:2024-05-03 04:43:24 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

Symbol

Symboles6引入的一个新的原始数据类型,是一个独一无二的值。

目前为止,js的数据类型有以下几种:

数据类型说明undefinedundefinednullnullboolean布尔值string字符串number数字Bigint大整数Object对象SymbolSymbol

Symbol通过Symbol()函数生成。对象的属性名现在除了可以使用字符串以外,还可以使用新增的Symbol类型。如果属性名使用Symbol,那么它就是独一无二的,不与其它属性名产生冲突。

lets=Symbol()console.log(typeofs);//symbol

注意:Symbol()函数前不能使用new,否则报错。因为生成的Symbol是一个原始类型的值,而不是对象,所以不能使用new来调用。而且,Symbol值不是对象,不能给Symbol添加属性。可以这么理解,Symbol是一种类似于字符串的数据类型。

Symbol接收字符串作为参数,表示对Symbol的描述,添加描述可以用来区分多个Symbol

lets2=Symbol('desc')lets3=Symbol('desc2')console.log(s2);//Symbol(desc)console.log(s3);//Symbol(desc2)

如果Symbol的参数传入的是对象,需要把对象转为字符串再生成Symbol,否则会显示[object Object]

letobj={name:'东方不败'}lets4=Symbol(JSON.stringify(obj))console.log(s4);//Symbol({"name":"东方不败"})lets5=Symbol(obj)console.log(s5);//Symbol([objectObject])

Symbol传入的参数只是一个描述,实际上SymbolSymbol并不相等。

letsy=Symbol()letsy2=Symbol()console.log(sy===s2);//falseletsy3=Symbol('a')letsy4=Symbol('a')console.log(sy3===sy4);//false

每调用一次Symbol()都会生成一个独一无二的值,每个Symbol都不相等。

Symbol值不能参与其他类型值的运算,否则报错。

leta=Symbol('hello')console.log(a+'world');//报错CannotconvertaSymbolvaluetoastring

Symbol转换

Symbol可以转换为字符串

leta2=Symbol('hello')console.log(String(a2));//Symbol(hello)

如果需要返回Symbol的描述需要使用es2019提供的Symbol实例属性description返回描述。

leta2=Symbol('hello')console.log(a2.description);//hello

Symbol可以转换为布尔值(boolean)

leta2=Symbol('hello')console.log(Boolean(a2));//trueconsole.log(Boolean(!a2));//false

Symbol属性名

Symbol作为属性名

letn=Symbol()//方式一letobj2={[n]:'东方不败'}console.log(obj2);//{Symbol():'东方不败'}console.log(obj2[n]);//东方不败//方式二obj2[n]='东方求败'console.log(obj2[n]);//东方求败//方式三letobj3={}letback=Object.defineProperty(obj3,n,{value:'艺术概论'})console.log(obj3[n]);//艺术概论

Object.defineProperty使用说明

  • 第一个参数:要在其上定义属性的对象

  • 第二个参数:要定义或修改的属性的名称

  • 第三个参数:将被定义或修改的属性描述符

Symbol值作为对象属性名时,不能用点运算符获得Symbol属性,使用点运算符相当于是给对象添加了一个字符串属性名,而不是获取Symbol

letn2=Symbol()letobj4={}console.log(obj4.n2='中国工艺美术史');//中国工艺美术史console.log(obj4[n2]);//undefinedconsole.log(obj4);//{n2:'中国工艺美术史'}

属性名遍历

Symbol是不可枚举的,Symbol作为对象键名时,是不可被遍历的,for...inObject.keys等方法都得不到Symbol键名,并且JSON.stringify()也不会返回Symbol

letm=Symbol('a')letf={[m]:'东方不败',name:'西方求败',name2:'光合作用'}//西方求败、光合作用for(kinf){console.log(f[k]);}console.log(Object.keys(f));//['name','name2']console.log(JSON.stringify(f));//{"name":"西方求败","name2":"光合作用"}

Reflect.ownKeys()可以返回常规键名和Symbol键名

console.log(Reflect.ownKeys(f));//['name','name2',Symbol(a)]

Object.getOwnPropertySymbols()只返回Symbol属性

console.log(Object.getOwnPropertySymbols(f));//[Symbol(a)]

Symbol.for()、Symbol.keyFor()

Symbol.for()Symbol有一个特性就是Symbol不等于Sombol,但有时候我们需要同一个Symbol

letr=Symbol.for('a')letr2=Symbol.for('a')console.log(r===r2);//true

Symbol.for()Symbol()都会生成新的Symbol,前者会被登记在全局环境提供搜索,后者不会。

Symbol.for()每次调用都会先检查参数key是否存在,如果不存在才会新建一个值。

Symbol()每次调用都会新建一个值。

Symbol.keyFor()Symbol.keyFor()返回已经登记的Symbol值的key

letr3=Symbol.for('b')letr4=Symbol('c')console.log(Symbol.keyFor(r3));//bconsole.log(Symbol.keyFor(r4));//undefined

Symbol内置值

Symbol.hasInstance

Symbol.hasInstance用来判断某个对象是否为某个构造器实例

classmyClass{static[Symbol.hasInstance](val){returntypeofval==='number'}//static[Symbol.hasInstance](val){//returntypeofval==='boolean'//}}console.log(100instanceofmyClass);//trueconsole.log('100'instanceofmyClass);//false

多个Symbol.hasInstance会覆盖,只保留最下面的那一个。

Symbol.isConcatSpreadable

Symbol.isConcatSpreadable用于表示Array.prototype.concat()是否可以展开,true、undefined可以展开,false不可展开。

letarr1=[1,2]letarr2=[3,4]console.log(arr1[Symbol.isConcatSpreadable]);//undefinedconsole.log(arr1.concat(arr2));//[1,2,3,4]

JavaScript中原始数据类型Symbol如何使用

console.log(arr1[Symbol.isConcatSpreadable]=false)console.log(arr1.concat(arr2));//[[1,2],3,4]

JavaScript中原始数据类型Symbol如何使用

Symbol.species

对象的Symbol.species属性指向一个构造函数,创建衍生对象时会使用该属性

//这里继承了Array的原型classMyArrayextendsArray{}leta=newMyArray(1,2,3)letb=a.map(el=>el+1)console.log(b);//constructor:classMyArray

JavaScript中原始数据类型Symbol如何使用

bc调用的是数组方法,那么应该是Array的实例,但实际上它们也是MyArray的实例

classMyArrayextendsArray{staticget[Symbol.species](){returnArray}}leta=newMyArray(1,2,3)letb=a.map(el=>el+1)letc=a.filter(el=>el==2)console.log(a,b,c);//1,2,32,3,42console.log(binstanceofMyArray);//falseconsole.log(b);//constructor:classMyArray

JavaScript中原始数据类型Symbol如何使用

Symbol.species可以在创建衍生对象时使用这个属性返回的函数作为构造函数。

这里returnArray,所以创建的衍生对象使用的Array作为构造函数,而不是MyArray

如果这里return一个String,那么上面的map、filter会报错,因为衍生对象使用的是String作为构造函数,String是没有数组方法的。

Symbol.match

Symbol.match指向一个函数,如果函数存在则会被调用,并返回该方法的返回值

classMyMatch{[Symbol.match](val){return'helloworld'.indexOf(val)}}//match字符串方法,可以在字符串内检索指定的值并返回console.log('e'.match(newMyMatch()));//1
 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:JavaScript中原始数据类型Symbol如何使用的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:PHP如何实现登录的Cookie存储下一篇:

4 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18