一、内置方法
- asyncIterator:异步迭代器. (property)
- iterator:迭代器。 (property)
- for 创建Symbol()Symbol.for() 类似单例模式,首先会在全局搜索被登记的 Symbol 中是否有该字符串参数作为名称的 Symbol 值,如果有即返回该 Symbol 值,若没有则新建并返回一个以该字符串参数为名称的 Symbol 值,并登记在全局环境中供搜索。
- keyFor Symbol.keyFor(sym) 方法用来获取全局 symbol 注册表中与某个 symbol 关联的键。
语法
Symbol.keyFor(sym);
//参数
// sym. (必选参数,需要查找键值的某个 Symbol 。)
- hasInstance
- isConcatSpreadable
- match
- matchAll
- replace
- split
- search
- species
- toPrimitive
- toStringTag
- unscopables
- useSetter
- useSimple
二、API解析
1、异步迭代器(asyncIterator)
- 定义:指定了一个对象的默认的异步迭代器,如果一个对象设置了这个属性,那么它就是异步可迭代对象,可用于for await…of 循环。
- 给一个对象添加asyncIterator属性:
let as_iterator=new Obiect();
as_iterator[Symbol.asyncIterator]=async function* (){
yield 'hello';
yield 'waiting';
yield 'ending';
}
(async()=>{
for await(let a of as_iterator){
console.log(a);
}
}())
【注:】暂时没有设置了[Symbol.asyncIterator]这个属性的JavaScript对象
2、### 迭代器(iterator)
- 定义:
为每一个对象定义了默认的迭代器,该迭代器可被【for...of】循环使用 - 拥有迭代器属性对象
- String
- Map
- Set
- Array
- arguments
- Typed Arrays (类数组)
- Generators
- 自定义迭代器:
1.利用generator函数:
let my_iterator = {
[Symbol.iterator] : function* () {
yield 'hello';
yield 'waiting';
yield 'ending';
}
}
console.log([...my_iterator]);
2.数据结构默认的Iterator接口,可以通过for…of使用。解构赋值用的也是Iterator接口。
const other_interator={
data:['hello',welcome,'world'],
[Symbol.interator](){
let ind=0;
return {
next:()=>ind<this.data.length?{value:this.data[ind++],done:false}:{value:undefined,}
}
}
}
let abs = other_iterator[Symbol.iterator]()
console.log(abs.next()); // {value: 'hello', one: false}
console.log(abs.next()); // {value: 'welcome', one: false}
console.log(abs.next()); // {value: 'world', one: false}
console.log(abs.next()); // {value: undefined, done: true}
3、for
- 定义:不同的变量可以使用同一个Symbol值,Symbol.for()方法接收一个参数,然后查找是否有以该参数作为名称的Symbol值,如果有就返回这个Symbol值,否则就新建一个以该参数为名称的Symbol值。
let a = Symbol('symbol')
let b = Symbol('symbol')
console.log(a === b); // false
let symbol_a = Symbol.for('symbol');
let symbol_b = Symbol.for('symbol');
console.log(symbol_a === symbol_b); // true
4、keyFor
定义:返回一个已使用的Symbol类型值的key,用来检测该参数作为名称的Symbol值是否已被使用
let a =Symbol.for('symbol');
let b=Symbol.for(a);
console.log(b)//symbol
console.log(a)//Symbol(symbol)
console.log(a===b) //false
5、hasInstance
-
定义:当我们使用instanceof这个方法去检测对象A是不是对象B的实例的时候,实际上B就是调用的B[Symbol.hasInstance]这个方法
- 常规使用
class Event {}
let e = new Event;
console.log(e instanceof Event); // true
console.log(Event[Symbol.hasInstance](e)); //true
- 更改 [Symbol.hasInstance] 指向
class my_instance {
static [Symbol.hasInstance](params) {
return typeof params
}
}
let a = new my_instance();
console.log(a instanceof my_instance); // true
console.log(my_instance[Symbol.hasInstance](a)); // object
6、isConcatSpreadable
- 定义:对象的Symbol.isConcatSpreadable属性等于一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。
let arr1 = ['c', 'd'];
['a', 'b'].concat(arr1, 'e') // ['a', 'b', 'c', 'd', 'e']
arr1[Symbol.isConcatSpreadable] // undefined
let arr2 = ['c', 'd'];
arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']
7、match
- 定义:指定了匹配的是正则表达式,而不是字符串。String.prototype.match会调用此方法。
String.prototype.match(regexp)
// 等同于
regexp[Symbol.match](this)
class MyMatcher {
[Symbol.match](string) {
return 'hello world'.indexOf(string);
}
}
'e'.match(new MyMatcher()) // 1
8、matcAll
- ** 定义**:返回一个迭代器,该迭代器根据字符串生成正则表达式的匹配项??梢员籟String.prototype.matchAll] 调用
const re = /[0-9]+/g;
const str = '2016-01-02|2019-03-07';
const result = re[Symbol.matchAll](str);
console.log(Array.from(result, x => x[0]));
// expected output: Array ["2016", "01", "02", "2019", "03", "07"]
9、replace
- 定义:对象的Symbol.replace属性,指向一个方法,当该对象被String.prototype.replace方法调用时,会返回该方法的返回值。
String.prototype.replace(searchValue, replaceValue)
// 等同于
searchValue[Symbol.replace](this, replaceValue)
下面这个例子
const x = {};
x[Symbol.replace] = (...s) => console.log(s);
'Hello'.replace(x, 'World') // ["Hello", "World"]
Symbol.replace方法会收到两个参数,第一个参数是replace方法正在作用的对象,上面例子是Hello,第二个参数是替换后的值,上面例子是World。
10、split
-
定义:指向一个正则表达式的索引处分隔字符串的方法。此方法通过【 String.prototype.split() 】调用。
其也是正则原型上的一个方法,在字符串使用split方法的时候会调用改方法。
class MySplitter {
constructor(value) {
this.value = value;
}
[Symbol.split](string) {
let index = string.indexOf(this.value);
if (index === -1) {
return string;
}
return [
string.substr(0, index),
string.substr(index + this.value.length)
];
}
}
'foobar'.split(new MySplitter('foo'))
// ['', 'bar']
'foobar'.split(new MySplitter('bar'))
// ['foo', '']
'foobar'.split(new MySplitter('baz'))
// 'foobar'
上面方法使用Symbol.split方法,重新定义了字符串对象的split方法的行为,
11、search
-
定义:指定了一个搜索方法,该方法接受一个正则表达式,该方法返回的是字符串中匹配到正则表达式的索引。此方法通过【String.prototype.search()】来调用。
1、正常使用:
let publicStr = 'anfdsvka fahF KJ'
let s= publicStr.search(/\a/g)
console.log(s); // 0
2、更改正则原型上的此方法
RegExp.prototype[Symbol.search] = () => {
return -1;
}
console.log(s); // -1
12、species
- 定义:对象的Symbol.species属性,指向一个构造函数。创建衍生对象时,会使用该属性。
class MyArray extends Array {
static get [Symbol.species]() { return Array; }
}
const a = new MyArray();
const b = a.map(x => x);
b instanceof MyArray // false
b instanceof Array // true
总之,Symbol.species的作用在于,实例对象在运行过程中,需要再次调用自身的构造函数时,会调用该属性指定的构造函数。它主要的用途是,有些类库是在基类的基础上修改的,那么子类使用继承的方法时,作者可能希望返回基类的实例,而不是子类的实例。
13、 toPrimitive
- 定义:是一个内置的Symbol值,它是作为对象的
let obj = {
[Symbol.toPrimitive](hint) {
switch (hint) {
case 'number':
return 123;
case 'string':
return 'str';
case 'default':
return 'default';
default:
throw new Error();
}
}
};
2 * obj // 246
3 + obj // '3default'
obj == 'default' // true
String(obj) // 'str'
14、toStringTag
- 定义:对象的Symbol.toStringTag属性,指向一个方法。在该对象上面调用Object.prototype.toString方法时,如果这个属性存在,它的返回值会出现在toString方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制[object Object]或[object Array]中object后面的那个字符串。
({[Symbol.toStringTag]: 'Foo'}.toString())
// "[object Foo]"
// 例二
class Collection {
get [Symbol.toStringTag]() {
return 'xxx';
}
}
let x = new Collection();
Object.prototype.toString.call(x) // "[object xxx]"
15、unscopables
- 定义: 指用于指定对象值,其对象自身和继承的从关联对象的 with 环境绑定中排除的属性名称。
const publicObj = {
a: '123',
b: '234',
c: undefined
}
publicObj[Symbol.unscopables] = {
a: true,
b: false
}
with(publicObj) {
console.log(a); // Uncaught ReferenceError: a is not defined
console.log(b); // '234'
console.log(c); // undefined
}
三、总结
1、asyncIterator 暂时无设置有该属性的JS对象;
2、iterator 迭代器,是在开发中可能会经常涉及到的一个Symbol属性,拥有该属性的数据类型包含:String、Array、arguments、Set、Map等;
3、hasInstance 在使用instanceof方法检测数据类型的时候,会优先调用此方法;
4、正则对象的原型上的方法包含:match、matcAll、replace、split、search
5、toStringTag 在使用 Object.prototype.toString() 去检测数据类型的时候,会优先调用 Symbol.toStringTag 这个方法