1.基本方法
let a=Symbol();//创建一个symbol
symbol本身是原始类型,所以typeof的时候返回symbol,而不是object
console.log(typeof a);
使用symbol时,能够传入一个字符串键值,但是这个参数与它本身的定义无关,而与人相关。
let a=Symbol();
let b=Symbol();
console.log(a === b);
即使好像a与b是一样的,但是它们还是不同,因为存储的地方不一样,所以false。
symbol也是即为特殊的,它和string, number, boolean都不同。它是孤独的,与new无缘,new一个会报错。
2.使用全局符号
所谓全局符号就是使用 Symbol.for()的方法来创建这个符号,它与普通的Symbol()创建不同,它是全局的,被存放在全局注册表里。
当使用 symbol.for 时,这个方法会对键值进行检索,如果存在则返回它,如果不存在就创建一个symbol并放入注册表里。
let a=Symbol.for('foo');
let b=Symbol.for('foo');
console.log(a === b);
这会返回true,因为他们是同一个符号。
还可以使用 symbol.keyfor 方法来查询键值,参数是符号,如果参数不是符号,则会报错,TypeError。
let a=Symbol.for('foo');
//let b=Symbol.for('foo');
console.log(Symbol.keyFor(a));//输出foo
3.符号作为属性
这点非常炫酷,它就像一个代号
object.defineProperty与object.defineProperties能够为对象添加符号属性。这是2个非常重要的方法。
let symArr = new Array();
for(let i=0;i<3;i++) {
symArr[i] = Symbol(i);
}
let obj={};
for(let i=0;i<symArr.length;i++) {
// 第一个参数 object
// 2 符号
// 3 对应的值
Object.defineProperty(obj,symArr[i],{value:i});
}
console.log(obj);
let sym1 = Symbol('1');
let sym2 = Symbol('a');
let sym3 = Symbol('b');
let a={};
a[sym1] = '123';
//第一个参数 object
//2 符号列表
Object.defineProperties(a,{
[sym2]:{value:'hello'},
[sym3]:{value:'world'}
});
console.log(a);
有创建,当然就有获取,它们分别是 Object.getOwnPropertySymbols | Object.getOwnPropertyNames | Object.getOwnPropertyDescriptors | Reflect.ownKeys
第一个函数返回对象实例的符号属性数组,第二个普通属性数组,3:包括前面2个的描述符对象,4:返回2个类型的属性
let sym1 = Symbol('1');
let sym2 = Symbol('a');
let sym3 = Symbol('b');
let a={m:'haha'};
a[sym1] = '123';
Object.defineProperties(a,{
[sym2]:{value:'hello'},
[sym3]:{value:'world'}
});
console.log(Object.getOwnPropertySymbols(a));
console.log(Object.getOwnPropertyNames(a));
console.log(Object.getOwnPropertyDescriptors(a));
console.log(Reflect.ownKeys(a));
看起来确实繁琐,不过用的时候也还好。
如果没有显示的保存引用,简单来说就是没有用变量存储它,那就必须进行查找,才能使用。
console.log(Object.getOwnPropertySymbols(a).find(Symbol=>Symbol.toString().match(/1/)));
well-known symbol 常用内置符号(es6引入的)
- symbol.asyncIterator
- symbol.isConcatSpreadable
- symbol.iterator
- symbol.match
- symbol.replace
- symbol.search
- symbol.species
- symbol.split
- symbol.toPrimitive
- symbol.toStringTag
- symbol.unscopables
我看到这些,满面问号?等我先研究研究,实在没这方面的经验。
3.1 第一个 symbol.asynclterator 它表示异步迭代器 API 函数
那么什么是叫异步呢?我以前以为js的异步就是多个任务同时进行,结果看了一篇大佬的文章发现,完全错误。
我用自己的话,概括一下异步操作的运行进制:
1. 程序运行时,所有的同步任务都会在主线程上运行,形成一条执行栈(栈是一种存储方式,先进后出(push,pop指令实现))
2. 主线程上,还存在一条任务队列,这玩意专门存放异步任务结果,感觉有点像钩子
3. 如果执行栈中的同步任务全部执行完毕,那么系统就会读取任务队列,并载入到执行栈执行。
总结起来:异步任务只有主线程调度的时候才会执行,什么时候调度呢,主线程把同步任务执行完毕时,其余时间,异步任务都待在任务列表里,等待被调度。
在这之前,我要了解一个新的玩意,它们分别是 async、Promise,await?.jpg
首先要了解一下async这个玩意,普通函数前面填一个async表示async函数,绕口令呢
语法:async function 某某函数名(一些有用的参数){ 执行的语句 }
async function testAsync(num){return num.toString();}
console.log(testAsync(123));
打印出来一个Promise{...},这说明async函数返回的是一个Promise对象。想要调用的话就必须使用then,then的参数是一个回调函数
testAsync(123).then(v=>{
console.log(v);
});
Promise对象,是一个异步操作对象,有3种状态,1.不是成功也不是失败,2.成功,3.失败
一共有2中变化,1->2或者1->3,一旦状态发生变化就不会再改变。
var myFirstPromise = new Promise(function(resolve, reject){
let randNum = Math.round(Math.random());
if (randNum == true) {
resolve('Ok');
} else {
reject('Error');
}
});
myFirstPromise.then(success=>{
console.log(success);
}).catch(reject=>{
console.log(reject);
});
未完,当做笔记挺好
南无阿弥陀佛,祝你吉祥!