Typescript新数据类型Symbol的使用

本文详细探讨了JavaScript中的Symbol数据类型,包括其唯一性、转换为布尔值、不可转换为Number的特点,以及在对象属性、模块、类方法等方面的应用。还介绍了全局Symbol注册表的使用,如`Symbol.for()`和`Symbol.keyFor()`,以及Symbol在数组展开、字符串方法、迭代器等方面的特殊行为。此外,文章还展示了如何利用Symbol实现自定义的数组方法和对象的`Symbol.toStringTag`属性,揭示了Symbol在创建独特标识符和定制对象行为方面的强大能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

let s = Symbol();
console.log(s);
console.log(typeof (s));
let s1 = Symbol('desc_name');
console.log(s1,typeof (s1),s1.toString());
console.log(Symbol()===Symbol());//false ,Symbol是唯一的
console.log(Boolean(Symbol()));//true ,Symbol可转换为bool类型,
console.log(String(Symbol()));
//console.log(Number(Symbol()));//Symbol不可转换为Number
let obj={}
obj[Symbol()]='hello';
console.log(obj);
let objA={
    [Symbol()]:'world'
}
console.log(objA);
let sym=Symbol();
let objB={
    [sym]:'helloworld',
    [Symbol('test')]:'testSymbol'
}
console.log(objB);
console.log(objB[sym]);
console.log(Object.getOwnPropertySymbols(objB));
//全局Symbol
let sym1 = Symbol.for('sym1');
let sym2 = Symbol.for('sym2');
let sym3 = Symbol.for('sym2');//存在,不重复创建,直接返回已存在
console.log(sym2===sym3);//true
//取Symbol.for中定义的key
console.log(Symbol.keyFor(sym2));

let a=require('./mod');//调用模块
console.log(a.foo);
console.log(global._foo);
global._foo = 123;
console.log(global._foo);
let b=require('./mod');//调用模块
console.log(b.foo);

class MyClass{
    [Symbol.hasInstance](foo){
        return foo instanceof Array;
    }
}

// @ts-ignore
if ([1, 2, 3] instanceof new MyClass()) {

}

//数组的展开使用
let arr1 = ['c','d'];
console.log( ['a','b'].concat(arr1,'e'));
console.log(arr1[Symbol.isConcatSpreadable]);//
arr1[Symbol.isConcatSpreadable] = false;//不展开数组
console.log( ['a','b'].concat(arr1,'e'));

class AA extends Array{
    constructor(...args) {
        super(...args);
        this[Symbol.isConcatSpreadable] = true;//展开数组
    }
}
class AB extends Array{
    constructor(...args) {
        super(...args);
        this[Symbol.isConcatSpreadable] = false;//不展开数组
    }
}

let aa1 = new AA([1,2,3,4,5]);
let aa2 = new AB([6,7,8,9,0]);
console.log([9,9,9].concat(aa1,aa2));

//Symbol.species指向当前对象的构造函数
class C extends  Array {
    constructor(...args) {
        super(...args);
        this[Symbol.isConcatSpreadable]=true;
    }
    //覆盖父类Array的构造函数
    static get [Symbol.species](){
        return Array;
    }
}

let cc = new C(1,2,3,4,5);
let ccMap = cc.map(x=>x *x);
console.log(ccMap instanceof C);
console.log(ccMap instanceof Array);//ccMap属于Array实例,因为Symbol.species覆盖了

console.log('hello'.match(/^he/i,));

class D {
    [Symbol.match](str){
        return 'hello'.indexOf(str);
    }
}

// @ts-ignore
console.log('e'.match(new D()));

const xx={};
xx[Symbol.replace] = (...s)=>console.log(s);
// @ts-ignore
'Hello'.replace(xx,'world');

class E {
    constructor(v) {
        this.v = v;
    }
    [Symbol.search](str){
        return str.indexOf(this.v);
    }
}
console.log( 'hello'.search(new E('e')));

class F {
    constructor(v) {
        this.v = v;
    }
    [Symbol.split](str){
        let i=str.indexOf(this.v);
        if (i===-1){return str;}
        return [str.substr(0,i),str.substr(i+this.v.length)];
    }
}
console.log( 'hello'.split(new F('e')));

let myIter = {};
myIter[Symbol.iterator] = function* (){
    yield 1;
    yield 2;
    yield 3;
};
// @ts-ignore
console.log([...myIter]);

//指向迭代器
class Collection {
    *[Symbol.iterator](){
        let i=0;
        while (this[i] !== undefined){
            yield this[i];
            ++i;
        }
    }
}

let myCol = new Collection();
myCol[0] = 1;
myCol[1] = 2;
myCol[2] = 3;
myCol[3] = 4;
myCol[4] = 5;
// @ts-ignore
for (const myColElement of myCol) {
    console.log(myColElement);
}

//指向原生对象
let objProto = {
    [Symbol.toPrimitive] (hint) {
        switch (hint){
            case 'number':
                return 123;
            case 'string':
                return 'hello';
            case 'default':
                return 'default';
            default:
                throw new Error('type Error');
        }
    }
};

// @ts-ignore
console.log(2*objProto);
console.log(objProto+'World');
console.log(objProto,objProto=='default',String(objProto));

//指向对象的标签
console.log(({[Symbol.toStringTag]:'Foo'}.toString()));

class Coll {
    get [Symbol.toStringTag](){
        return 'xxx';
    }
}
let CollObj = new Coll();
console.log(Object.prototype.toString.call(CollObj));
console.log(CollObj);

console.log(JSON[Symbol.toStringTag]);
console.log(Math[Symbol.toStringTag]);
console.log(ArrayBuffer.prototype[Symbol.toStringTag]);
console.log(aa1[Symbol.toStringTag]);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

自由软件开发者

有你的鼓励,我会更加努力。

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

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

打赏作者

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

抵扣说明:

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

余额充值