Skip to content

Commit 70f0503

Browse files
committed
chore(ci): blog sync
1 parent e5832bf commit 70f0503

File tree

4 files changed

+382
-0
lines changed

4 files changed

+382
-0
lines changed

data/blog/Async、Awiteyuanli.mdx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
title: Async、Awite原理
3+
date: 2023-12-23T12:50:11Z
4+
summary:
5+
tags: []
6+
---
7+
8+
我想在异步中调用一个异步,在在这个异步中调用一个异步
9+
```
10+
function require(url) {
11+
return new Promise((resolve, reject) => {
12+
setTimeout(() => {
13+
resolve(url);
14+
}, 2000);
15+
});
16+
}
17+
18+
require("url").then((res) => {
19+
require(res + "url2").then((res) => {
20+
require(res + "url3").then((res) => {
21+
console.log(res);
22+
});
23+
});
24+
});
25+
```
26+
27+
回调地狱产生了,显然这个不是一个好的办法,有更好的办法
28+
```
29+
//方案一
30+
require("url")
31+
.then((res) => {
32+
return require(res+"url2");
33+
})
34+
.then((res) => {
35+
return require(res+"url3");
36+
})
37+
.then((res) => {
38+
console.log(res);
39+
});
40+
41+
//promise+generator
42+
function* urlGenerator() {
43+
const res1 = yield require("url");
44+
const res2 = yield require(res1+"url2")
45+
yield require(res2+"url3")
46+
}
47+
//怎么还是回调地狱
48+
const generator = urlGenerator();
49+
generator.next().value.then((res) =>{
50+
generator.next(res).value.then(res=>{
51+
generator.next(res).value.then(res=>{
52+
console.log(res);
53+
})
54+
})
55+
});
56+
//使用递归来实现
57+
function execGenerator(generatorFn) {
58+
const generator = generatorFn();
59+
function exec(res) {
60+
const result = generator.next(res);
61+
if (result.done) {
62+
return result.value;
63+
}
64+
result.value.then((res) => {
65+
exec(res);
66+
});
67+
}
68+
exec();
69+
}
70+
execGenerator(urlGenerator)
71+
72+
//其实并不需要那么的复杂
73+
async function urlGenerator() {
74+
const res1 = await require("url");
75+
const res2 = await require(res1 + "url2");
76+
const res3 = await require(res2 + "url3");
77+
console.log(res3);
78+
}
79+
80+
urlGenerator()
81+
```
82+
## async/awite
83+
async/awite的本质就是promise和generator
84+
async里面的被awite的异步代码会同步执行
85+

data/blog/ES6dixin特xing(er).mdx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
title: ES6的新特性(二)
3+
date: 2023-12-23T12:49:13Z
4+
summary:
5+
tags: []
6+
---
7+
8+
## Symbol
9+
```
10+
//symbol能生成一个独一无二的值,可以给该值添加一个描述
11+
let a = Symbol("ada")
12+
console.log(a.description);
13+
```
14+
symbol可以作为对象的key
15+
symbol.for()/symbol.keyfor()
16+
## 数据结构Set
17+
set里面不会出现相同的元素,可以用于数组去重
18+
```
19+
const set = new Set()
20+
//add:添加一个元素
21+
set.add(1)
22+
set.add(2)
23+
set.add(1)
24+
console.log(set);
25+
//输出Set(2) { 1, 2 }
26+
27+
//delete:删除一个元素
28+
set.delete(1)
29+
console.log(set);
30+
//输出Set(1) { 2 }
31+
32+
//clear:清空所有元素
33+
set.clear()
34+
console.log(set);
35+
//Set(0) { }
36+
37+
//has:是否包含某个元素
38+
set.has(2)
39+
//包含返回true,不包含返回false
40+
```
41+
## 数据结构weakSet
42+
???weakSet和set有啥区别?
43+
weakSet只能存放对象类型,并且对对象的引用是个弱引用,没办法做遍历操作
44+
???什么是弱引用?
45+
对于浏览器而言,弱引用相当于这个指向不存在,还是会被垃圾回收
46+
弱引用存在的意义在于能让其访问到相应的值
47+
## 数据结构Map
48+
用于存储映射关系,对象中是不允许对象类型作为key的,而在map中可以
49+
```
50+
let obj1 = {name:"inwind"}
51+
let obj2 = {height:18.8}
52+
53+
let map = new Map([[obj1,"123"],[obj2,"456"]])
54+
console.log(map);
55+
//输出Map(2) { { name: 'inwind' } => '123', { height: 18.8 } => '456' }
56+
```
57+
方法map.set()、map.get、map.has()、map.delete()、map.clear()、
58+
### map和object有什么区别
59+
map是可迭代对象,object不是,可以用Object.entries()、Object.keys()、Object.value进行迭代
60+
map的key可以是任意值,而object的值只能是string或者symbol
61+
map里存放有几个键值对可以通过Map.size轻松获取,而object只能自行获取
62+
## 数据结构weakMap
63+
key只能是对象,存放的对象的引用是个弱引用
64+
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
title: ES6的新特性(三)
3+
date: 2023-12-23T12:49:31Z
4+
summary:
5+
tags: []
6+
---
7+
8+
## Array.prototype.includes
9+
判断数组中是否存在该元素
10+
arr.includes(判断的元素,从第几个下标开始)
11+
## 平方运算符
12+
计算3的3次方
13+
3**3
14+
## Object.value()
15+
之前有一个Object.key方法能拿到对象所有的key
16+
这个是与之对应的拿到对象所有的value
17+
## Object.entries()
18+
将对象的键值对放入数组
19+
```let obj = {
20+
name:"inwind",
21+
age:18,
22+
height:18.8
23+
}
24+
25+
console.log(Object.entries(obj));
26+
```
27+
## String.prototype.padStart和String.prototype.padEnd
28+
```const text = "我是inwind"
29+
const newtext = text.padStart(15,"*")
30+
//使用*将字符串从开头填充到十五位
31+
console.log(newtext);
32+
33+
const text = "我是inwind"
34+
const newtext = text.padEnd(15,"*")
35+
//使用*将字符串从结尾填充到15位
36+
console.log(newtext);
37+
```
38+
## Array.prototype.flat和Array.prototype.flatMap
39+
```
40+
const arr = [1,[2,3],[4,5,[6,7],8],9,10]
41+
//给对应数组降维,默认值是1
42+
const newArr = arr.flat()
43+
console.log(newArr);
44+
```
45+
flatMap顾名思义,flat和map的结合。。。
46+
## Object.fromEntries
47+
之前的文章提到object.entrises可以把一个对象键值对转化为数组并由数组包裹
48+
而fromEntries可以将这种格式转回成对象
49+
```
50+
const obj = {name:"inwind",age:18,height:1.88}
51+
const newObj = Object.entries(obj)
52+
console.log(newObj);
53+
//输出[ [ 'name', 'inwind' ], [ 'age', 18 ], [ 'height', 1.88 ] ]
54+
55+
const oldObj = Object.fromEntries(newObj)
56+
console.log(oldObj);
57+
//输出{ name: 'inwind', age: 18, height: 1.88 }
58+
```
59+
## String.prototype.trimStart和String.prototype.trimEnd
60+
与trim同理,去除字符串前面的空格or后面的空格
61+
## bigInt
62+
Number.MAX_SAFE_INTEGER可以获取到js中数的最大值为9007199254740991,不能再继续往上计算
63+
而使用bigInt类型可以,
64+
```
65+
const bigInt = 9007199254740991n
66+
console.log(Number(bigInt+7n));
67+
```
68+
## ??逻辑空运算符
69+
```
70+
let a = null
71+
//当前面一个为null或undfined时,执行后面一个
72+
let b = a ?? "default value"
73+
74+
console.log(b);
75+
```
76+
## 可选链
77+
```
78+
let obj = {
79+
name:"inwind",
80+
friend:{
81+
name:"katom",
82+
}
83+
}
84+
//当查找不到某个值时,返回undfined
85+
console.log(obj.friend?.name);
86+
console.log(obj.friend?.age);
87+
```
88+
## globalThis
89+
获取当前的全局对象
90+
在浏览器环境下获取的是window,在node环境下获取的是global
91+
## finalizationRegistry类
92+
你可以在里面注册一个对象,在对象被GC垃圾回收时时,会回调传入的函数
93+
```
94+
let obj = {name:"inwind",height:18.8}
95+
const finalization = new FinalizationRegistry(()=>{
96+
console.log("被销毁了");
97+
})
98+
//注册一个对象,可以传入一个值,这个值被作为回调函数的参数
99+
finalization.register(obj,"value")
100+
obj = null
101+
```
102+
## weakRef对引用类型建立一个弱引用
103+
```
104+
//用以上代码来进行验证,多添加一个引用,该对象依旧被销毁,可见这是一个弱引用
105+
let obj = { name: "inwind", height: 18.8 };
106+
let info = new WeakRef(obj)
107+
const finalization = new FinalizationRegistry(() => {
108+
console.log("被销毁了");
109+
});
110+
111+
finalization.register(obj, "value");
112+
obj = null;
113+
```
114+
如果想获取弱引用对象的属性,不能直接获取,
115+
如获取name,要使用info.deref().name获取
116+
## 新的运算符
117+
* 1、||= 逻辑或赋值运算
118+
* 2、&&= 逻辑与赋值运算
119+
* 3、??= 逻辑空赋值运算
120+
```
121+
let a = undefined
122+
a||="default value"
123+
//相当于a=a||"default value"
124+
125+
a&&="default value"
126+
//相当于a=a&&"default value"
127+
128+
a??="default value"
129+
//相当于a=a??"default value"
130+
```
131+

data/blog/diedaiqiheshengchengqi.mdx

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
title: 迭代器和生成器
3+
date: 2023-12-23T12:49:47Z
4+
summary:
5+
tags: []
6+
---
7+
8+
## 什么是迭代器
9+
迭代器(iterator)能让我们在某个数据结构上进行遍历的对象
10+
在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。 更具体地说,迭代器是通过使用 next() 方法实现迭代器协议(Iterator protocol)的任何一个对象,该方法为无参数或者一个参数的函数
11+
该方法返回具有两个属性的对象: value,这是序列中的 next 值;和 done ,如果已经迭代到序列中的最后一个值,则它为 true 。如果 value 和 done 一起存在,则它是迭代器的返回值。
12+
一旦创建,迭代器对象可以通过重复调用next()显式地迭代。 迭代一个迭代器被称为消耗了这个迭代器,因为它通常只能执行一次。 在产生终止值之后,next()返回{donetrue}
13+
```
14+
//实现一个迭代器
15+
const arr = ['aaa','bbb','ccc','ddd']
16+
17+
let i = 0
18+
const iterator = {
19+
next:function(){
20+
if(i<arr.length){
21+
return {done:false,value:arr[i++]}
22+
}else{
23+
return {done:true,value:undefined}
24+
}
25+
}
26+
}
27+
28+
console.log(iterator.next());
29+
console.log(iterator.next());
30+
console.log(iterator.next());
31+
console.log(iterator.next());
32+
console.log(iterator.next());
33+
```
34+
## 可迭代对象
35+
若一个对象拥有迭代行为(即能返回一个迭代器),比如在 for...of 中会循环哪些值,那么那个对象便是一个可迭代对象。一些内置类型,如 Array 或 Map 拥有默认的迭代行为,而其他类型(比如Object)则没有。
36+
为了实现可迭代,一个对象必须实现返回一个迭代器,这意味着这个对象(或其原型链中的任意一个对象)必须具有一个带 Symbol.iterator 键(key)的属性。
37+
```
38+
const iteratorObj = {
39+
arr: ["aaa", "bbb", "ccc", "ddd"],
40+
[Symbol.iterator]: function () {
41+
let i = 0;
42+
//返回一个迭代器
43+
return {
44+
next:() => {
45+
if (i < this.arr.length) {
46+
return { done: false, value: this.arr[i++] };
47+
} else {
48+
return { done: true, value: undefined };
49+
}
50+
},
51+
};
52+
},
53+
};
54+
55+
const iterator = iteratorObj[Symbol.iterator]();
56+
console.log(iterator.next());
57+
console.log(iterator.next());
58+
console.log(iterator.next());
59+
console.log(iterator.next());
60+
console.log(iterator.next());
61+
//此时就解除了一个之前的疑惑,为什么for of遍历不了一个对象,因为对象不是一个可迭代对象
62+
for(let item of iteratorObj){
63+
console.log(item);
64+
}
65+
66+
//创建一个数组,数组里会内置有可迭代对象
67+
let arr = ["aaa", "bbb", "ccc", "ddd"];
68+
console.log(arr[Symbol.iterator]);
69+
let iterator = arr[Symbol.iterator]()
70+
console.log(iterator.next());
71+
console.log(iterator.next());
72+
console.log(iterator.next());
73+
console.log(iterator.next());
74+
console.log(iterator.next());
75+
```
76+
## 会自动生成迭代器的数据结构或对象
77+
String、Array、Set、Map、arguments、NodeLsit
78+
#生成器(generator)
79+
虽然自定义的迭代器是一个有用的工具,但由于需要显式地维护其内部状态,因此需要谨慎地创建。生成器函数提供了一个强大的选择:它允许你定义一个包含自有迭代算法的函数, 同时它可以自动维护自己的状态。 生成器函数使用 function*语法编写。 最初调用时,生成器函数不执行任何代码,而是返回一种称为Generator的迭代器。 通过调用生成器的下一个方法消耗值时,Generator函数将执行,直到遇到yield关键字。
80+
上面是 mdn 的解释,通俗的来讲,yield就是形成了一个个断点
81+
```
82+
//生成器
83+
function*generatorFn(){
84+
85+
console.log("代码执行开始");
86+
87+
const a = 2
88+
yield a
89+
90+
const b = 3
91+
yield b
92+
console.log("代码执行完毕");
93+
return "asdasdas"
94+
}
95+
96+
let generator = generatorFn()
97+
console.log(generator.next());
98+
//next()可以传入一个参数,这个参数会作为上一个yield的返回值
99+
console.log(generator.next());
100+
console.log(generator.next());
101+
```、
102+

0 commit comments

Comments
 (0)