【JS】Symbol

Symbol

  • 用途:确保对象属性使用唯一标识符,不会发生属性命名冲突

  • Symbol()创建,参数为描述

  • 不能使用new

  • 不能与其他类型运算

    • 只能转为字符串或布尔值
  • 在对象内不会自动转换为字符串

  • 不能使用.,只能用[]

Symbol.for

  • Symbol.for()Symbol()这两种写法,都会生成新的Symbol对象

  • Symbol.for():会保存在全局注册表中,如果描述相同则不会生成新的,而是重复调用

    没有参数则描述为undefined

    const s1=Symbol.for('1')
    const s2=Symbol.for('1')
    console.log(s1===s2);//true
    const s3=Symbol('1')
    console.log(s1===s3);//false
    
  • Symbol.keyFor() 可以查询全局注册表,参数为全局注册过的Symbol对象

    let s = Symbol.for('foo');
    console.log(Symbol.keyFor(s)); // foo
    

方法

  • Reflect.ownKeys(obj):返回自身所有属性(包括Symbol属性)
  • Object.getOwnPropertySymbols(obj):返回自身所有Symbol属性
  • Object.getOwnPropertyDescriptors() :返回自身所有描述对象(包括Symbol属性)
  • Object.assign:对象合并(识别symbol

内置Symbol属性

Symbol.hasInstance()

class Baz {
    static [Symbol.hasInstance](obj) {}
}
  • 在使用instanceof运算符时调用

Symbol.isConcatSpreadable

arrayLikeObject[Symbol.isConcatSpreadable] = true;
  • 值为布尔值,在Array.prototype.concat()时,用于判断是否展开(一层)
  • 数组的默认行为是可以展开

Symbol.iterator

class Emitter {
    constructor(max) {
        this.max = max;
        this.idx = 0;
	}	
	*[Symbol.iterator]() {
		while(this.idx < this.max) {
			yield this.idx++;
		}
	}
}

function count() {
	let emitter = new Emitter(5);
	for (const x of emitter) {
		console.log(x);
	}
}
count();	
  • 对象进行for...of循环时调用
  • 函数应该返回遍历器

Symbol.asynIterator

class Emitter {
    constructor(max) {
        this.max = max;
        this.idx = 0;
    }
    //生成器在类中的写法
    *[Symbol.iterator]() {
        while (this.idx < this.max) {
            yield this.idx++;
        }
    }
}
async function asyncCount() {
    let emitter = new Emitter(5);
    for await(const x of emitter) {
    	console.log(x);
    }
}
asyncCount();
// 0
// 1
// 2
// 3
// 4
  • 对象进行for await...of循环时调用

Symbol.match

class FooMatcher {
    static [Symbol.match](str) {}
}
  • 在使用String.prototype.match()时调用

Symbol.replace

class FooReplacer {
	static [Symbol.replace](target, replacement) {}
}
  • 在使用String.prototype.replace()时调用

Symbol.search

class FooSearcher {
	static [Symbol.search](target) {}
}
  • 在使用String.prototype.search()时调用

Symbol.species(常用)

class MyArray extends Array {
    static get [Symbol.species]() {
        console.log('创建了衍生对象');
    }
}
const a = new MyArray(1, 2, 3);
const b = a.map(x => x); //创建了衍生对象
const c = a.filter(x => x > 1); //创建了衍生对象
  • 创建衍生对象时调用
  • 注意要采用get取值器

Symbol.split

class FooSplitter {
	static [Symbol.split](target) {}
}
  • 在使用String.prototype.split()时调用

Symbol.toPrimitive

class Bar {
    constructor() {
        this[Symbol.toPrimitive] = function (hint) {
            switch (hint) {
                case 'number':
                    return 3;
                case 'string':
                    return 'string bar';
                case 'default':
                default:
                    return 'default bar';
            }
        }
    }
}
let bar = new Bar();
console.log(3 + bar); // "3default bar"
console.log(3 - bar); // 0
console.log(String(bar)); // "string bar"
  • 对象被转为原始类型时调用
  • 返回该对象对应的原始类型值
  • 接受一个字符串参数,表示当前运算的模式:
    • Number:需要转成数值
    • String:需要转成字符串
    • Default:可以转成数值,也可以转成字符串

Symbol.toStringTag

class Collection {
  get [Symbol.toStringTag]() {
    return 'xxx';
  }
}
let x = new Collection();
Object.prototype.toString.call(x) // "[object xxx]"
  • Object.prototype.toString()时调用
  • 返回值可以用来定制数据类型[object 定制]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值