Symbol类型详解

  1. symbol类型通过Symbol函数生成,用于表示独一无二的值(不使用new关键字,直接调用即可创建。例:const s = Symbol("str"))

  1. 即使使用相同的字符串来创建Symbol类型的值,这些值也是不同的

3. symbol值可以调用 toString方法,也可以通过Boolean()转为 布尔值

a.symbol本身转为布尔值时为true,取反为false

b.toString调用后会返回Symbol(str)

4. 在ES6中,支持用表达式 (变量)作为属性名,但表达式必须放在方括号里,由于每个Symbol值都是独一无二的,就可以用Symbol值作为属性名,且不会和其他属性名重复

5. 使用symbol值作为属性名的属性访问只能使用name和 这个symbol值,例:obj[name]

6. 属性名遍历

a. symbol类型的属性并不是私有属性,但不能通过for in遍历到,也不能被Object.keys() ,Object。getOwnProperNames(),Json.stringify()获取到

b. symbol类型属性名可以通过Object.getOwnPropertySymbol()获取,但只能获取到symbol类型的属性名

c. 使用ES6新提供的Reflect对象的 静态方法Reflect.ownKeys()可以获取全部属性名 ,包括symbol类型和非symbol类型

7. symbol的静态方法

a. Symbol.for()

使用Symbol.fro()方法传入字符串,会先检查有没有使用这个字符串调用Symbol.for创建的symbol值,如果有,就返回该值,没有则进行创建

通过Symbol.for创建的symbol值是全局范围内的

b. Symbol.keyFor()

调用Symbol.keyfor传入一个symbol值可以返回该值在全局注册的键名,例

const sym = Symbol.for("aaa");
console.log(Symbol.keyFor(sym));
//会返回aaa

8. ES6的11个内置Symbol值

a. Symbol.hasInstance

对象的Symbol.hasInstance指向一个内部方法,如果给一个对象设置了以Symbol.hasInstance为属性名的方法,当其他对象使用instanceof来判断是否为该对象实例时,会调用这个方法,传入的参数为被判断的这个对象

const obj = {
    [Symbol.hasInstance](obj2){
        console.log('obj2');
        //调用后会打印出{a:111}这个对象
    }
};

console.log({a:111} istanceof obj);
//{a:111}会作为obj2传入Symbol.hasInstance

b. Symbol.isConcatSpreadable

该属性是一个可读写的布尔值,默认值为undefined,该属性控制数组是否能被扁平化,当值为false时,数组不能被扁平化,为true或undefined则可以,例:

let arr1 = [1,2];
console.log([].concat(arr1,[3,4]));
//打印结果为[1,2,3,4]
console.log(arr1[Symbol.isConcatSpreadable]);
//此时该属性值为默认的undefined

arr1[Symbol.isConcatSpreadable] = true;
//把属性值设置为true
console.log([].concat(arr1,[3,4]));//结果同上
console.log(arr1[Symbol.isConcatSpreadable]);
//属性值为true

arr1[Symbol.isConcatSpreadable] = false;
//再设置为false
console.log([].concat(arr1,[3,4]));
//此时的结果变成了[Array(2), 3, 4]
//展开后是[[1, 2, Symbol(Symbol.isConcatSpreadable): false],3,4]
//这里的Symbol(Symbol.isConcatSpreadable): false]不是一个元素,而是一个属性
console.log(arr1[Symbol.isConcatSpreadable]);
//false

c. Symbol.species

定义一个类C,使其继承自Array,再给类C创建一个实例对象c,c就能继承Array原型对象上的方法,通过c的map方法衍生一个a对象,分别打印a instanceof C和a instanceof Array,发现结果都为true,说明a既是C的实例对象,也是Array的实例对象

class C extends Array{
    getName(){
        return 'aaa';
    }
};
const c = new C(1,2,3);
const a = c.map(item=>item+1)
console.log(a instanceof Array)
console.log(a instanceof C)//两个结果都为true
console.log(a.getName())//aaa

如果需要让a只是Array的实例而不是C的实例,就需要使用Symbol.species,给C定义一个名为Symbol.specied的静态get存取器方法,并在该方法中返回要构造衍生数组的构造函数

class C extends Array{
    static get[Symbol.species](){
        retrun Array;
    }
    getName(){
        return 'aaa';
    }
};
const c = new C(1,2,3);
const a = c.map(item=>item+1)
console.log(a instanceof Array)//打印true
console.log(a instanceof C)//结果为false
console.log(a.getName())//a不是C的实例,也不能调用getName方法,会报错a.getName is not a function

d. Symbol.match,Symbol.replace,Symbol.search,Symbol.split

这四个都指向一个内部方法,当在字符串上调用match,replace,search,和split方法时,会调用这个方法

let obj = {
  [Symbol.match](str){
    return str.length
  }
};

console.log('aaaaa'.match(obj));//返回值为5

e. Symbol.iterator

数组的Symbol.iterator方法指向该数组的默认遍历器方法,该属性是可写的,可以自定义遍历器方法

f. Symbol.toPrimitive

Symbol.toPrimitive指向一个内部方法,当对象被转为原始类型是会调用这个方法,这个方法的参数是该对象被转为的类型

const obj = {
  [Symbol.toPrimitive](type){
    console.log(type);
  }
};

const a = obj++
//调用方法后会打印number

g. Symbol.toStringTag

对象的Symbol.toStringTag属性可以是一个字符串也可以是一个存取器get方法,当对象调用toString方法时,会返回[object 返回值]

let obj = {
    //属性值为存取器get方法
  get [Symbol.toStringTag](){
    return 'aaa';
  }
};

let obj2 = {
    //字符串属性值
  [Symbol.toStringTag]:'bbb'
}

console.log(obj.toString());
//打印[object aaa]
console.log(obj2.toString());
//打印[object bbb]

h. Symbol.unscopables

对象的该属性指向一个对象,可以控制这个对象的属性是否被with环境过滤

const obj={
  a:111,
  b:222,
  c:333,
}

obj[Symbol.unscopables]={
  a:true,
  b:false
}

with(obj){
  // console.log(a);
    //因为对a设置为了true,所以a属性会被with环境过滤掉,不能通过with访问,会报错
  console.log(b);//222
  console.log(c);//333
}

console.log(obj[Symbol.unscopables]);
//{a: true, b: false}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开源商城源码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值