Skip to content

Commit 6ce97c2

Browse files
committed
chore(ci): blog sync
1 parent 392750c commit 6ce97c2

File tree

3 files changed

+321
-0
lines changed

3 files changed

+321
-0
lines changed

data/blog/mianxiangduixiang.mdx

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
title: 面相对象
3+
date: 2023-12-23T12:44:44Z
4+
summary:
5+
tags: []
6+
---
7+
8+
## 面向对象的三大特性
9+
### 封装
10+
### 继承
11+
### 多态
12+
## Object.defineProperty()
13+
使用Object.defineProperty在obj上创建一个新的属性后打印
14+
```
15+
var obj = {
16+
name:"inwind",
17+
age:18,
18+
}
19+
20+
Object.defineProperty(obj,"height",{
21+
value:"188",
22+
})
23+
24+
console.log(obj);
25+
console.log(obj.height);
26+
```
27+
卧槽,为什么直接打印obj,没有height属性,但直接打印obj.height却打印地出来
28+
因为创建出来的height不是一个可枚举的属性
29+
## 属性描述符
30+
Object.defineProperty()的第三个参数,分为数据属性描述符和存取属性描述符。
31+
![属性描述符](http://82.157.237.225:4000/images/属性描述符.jpg)
32+
```
33+
var obj = {
34+
name:"inwind",
35+
age:18,
36+
}
37+
//
38+
Object.defineProperty(obj,"height",{
39+
value:"188",
40+
//是否可删除(默认为false)
41+
configurable:false,
42+
//是否可迭代(默认为false)
43+
enumerable:true
44+
//是否可写入(默认为false)
45+
writable:true
46+
})
47+
48+
Object.defineProperty(obj,"height",{
49+
configurable:true,
50+
enumerable:true,
51+
get(){
52+
console.log("获取到了");
53+
},
54+
set(value){
55+
console.log("设置了新值"+value);
56+
}
57+
})
58+
59+
obj.height = "asd"
60+
```
61+
## 获取一个属性描述符Object.getOwnPropertyDescriptor
62+
console.log(Object.getOwnPropertyDescriptor(obj,"height"));
63+
## 获取对象所有的属性描述符Object.getOwnPropertyDescriptors
64+
console.log(Object.getOwnPropertyDescriptor(obj));
65+
## 对象的原型
66+
每个对象都有一个__proto__属性,可以称为对象的隐式原型
67+
## 函数的原型
68+
函数也是个对象,所以它也有__proto__属性,同时函数有一个prototype属性,称之为显式原型
69+
![创建对象的内存表现](http://82.157.237.225:4000/images/创建对象的内存表现.jpg)
70+
71+
fn和fn的原型对象的指向是一个闭环,甚至可以fn.prototype.constructor.prototype.constructor 。。。
72+
## 原型链
73+
当在访问对象的属性时,如果找不到,就会到__proto__对象上查找,如果还是找不到,继续向上,这就叫做原型链
74+
## new一个对象执行了怎么操作
75+
1、创建一个空对象
76+
2、this赋值
77+
3、将Object.prototype赋值给该对象的__proto__
78+
## Object原型
79+
Object是最顶层的原型,Object原型上有很多方法
80+
## 原型链继承
81+
继承旨继承属性和方法,两个不相干的构造函数,实现让student继承person的属性,由图可以看到,student将指针指向了person的对象完成了继承,如果在定义studying方法之后才完成继承,那么这个方法将会丢失
82+
```
83+
function person() {
84+
this.name = "inwind";
85+
}
86+
person.prototype.eating = () => {
87+
console.log("人吃饭");
88+
};
89+
90+
student.prototype = new person()
91+
92+
function student() {
93+
this.id = "12138";
94+
}
95+
student.prototype.studying = () => {
96+
console.log("学生学习");
97+
};
98+
99+
100+
const stu = new student()
101+
stu.eating()
102+
stu.studying()
103+
```
104+
![原型链继承图解](http://82.157.237.225:4000/images/原型链继承图解.jpg)
105+
原型链继承的弊端:继承的属性是不可枚举的(直接打印对象看不到)。如果继承的构造函数new了两个对象,修改他们的属性,如果这个属性是通过查找原型链来获取的,那么他们的属性是会互相影响的。如果继承的构造函数有参数,那么便不好处理
106+
```
107+
function person(name) {
108+
this.name = name;
109+
}
110+
person.prototype.eating = () => {
111+
console.log("人吃饭");
112+
};
113+
114+
student.prototype = new person("inwind")
115+
116+
function student(id) {
117+
person.call(this,id)
118+
this.id = id;
119+
}
120+
student.prototype.studying = () => {
121+
console.log("学生学习");
122+
};
123+
124+
125+
const stu = new student(123)
126+
127+
console.log(stu);
128+
```
129+
这种方案能解决以上问题,不过还是有弊端,person函数被调用了两次
130+

data/blog/shousipromise.mdx

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
title: 手撕promise
3+
date: 2023-12-23T12:44:27Z
4+
summary:
5+
tags: []
6+
---
7+
8+
## promise?
9+
Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。
10+
在此前,如果要使用一个异步的库,这时候要传入回调函数,这对我们来说就是一个黑盒子,如果你不阅读他的文档或者源码,根本不知道需要传什么东西,而且在多次调用异步函数时,会形成回调地狱,代码会变得非常地不优雅,难以阅读。
11+
使用promise可以规范好代码的逻辑,调用时直接调用,很nice。
12+
```
13+
//模拟发送网络请求函数
14+
function request(url,callbackSuccess,callbackError){
15+
settimeout(()=>{
16+
if(url==="home"){
17+
//请求成功
18+
let res = "data"
19+
callbackSuccess(res)
20+
}else{
21+
//请求失败
22+
let err = "请求失败"
23+
callbackError(err)
24+
}
25+
},3000)
26+
27+
const callbackSuccess = (res)=>{
28+
console.log(res)
29+
}
30+
31+
const callbackError = (err)=>{
32+
console.log(err)
33+
}
34+
}
35+
36+
//使用promise
37+
function request(url){
38+
return new Promise((resolve,reject)=>{
39+
settimeout(()=>{
40+
if(url==="home"){
41+
//请求成功
42+
let res = "data"
43+
resolve(res)
44+
}else{
45+
//请求失败
46+
let err = "请求失败"
47+
reject(err)
48+
}
49+
},3000)
50+
})
51+
}
52+
53+
//这个存在多种写的,可以分开写、链式调用、也可以将回调都传入then参数里面
54+
request("/home").then((res)=>{
55+
......
56+
}).catch((err)=>{
57+
......
58+
})
59+
```
60+
## promise的三个状态
61+
promise有三个状态:pending(进行中)、fulfilled(已敲定)、rejected(已拒绝),状态一旦确定下来就不会更改了
62+
特殊情况:如果一个promise传入了一个promise,那么这个promise状态的决定权就会交到传入的promise上
63+
## promise的finally方法
64+
```
65+
//finally:不接收参数,无论前面的状态是fulfilled还是rejected,代码都会执行
66+
promise.then().catch().finally(()=>{})
67+
```
68+
## promise的resolve or reject方法
69+
```
70+
//promise的resolve方法
71+
//直接进行resolve
72+
let promise = new Promise.resolve("res")
73+
74+
let promise = new Promise.reject("err")
75+
```
76+
## promise的all方法
77+
```
78+
Promise([promise1,promise2,promise3,"随便"]).then(res=>{
79+
//当所有参数中所有的promise都fulfilled之后,返回一个所有结果组成的数组
80+
//如果传入一个非promise,则自动将它resolve
81+
console.log(res)
82+
}.catch(err=>{
83+
//当有一个promise rejected时,它的状态就会变成reject
84+
console.log(err)
85+
})
86+
})
87+
```
88+
## promise的allSettled方法
89+
```
90+
const p1 = new Promise((resolve)=>{
91+
resolve("p1 resolve")
92+
})
93+
94+
const p2 = new Promise((resolve,reject)=>{
95+
reject("p2 reject")
96+
})
97+
98+
const p3 = new Promise((resolve)=>{
99+
resolve("p3 resolve")
100+
})
101+
102+
Promise.allSettled([p1,p2,p3]).then(res=>{
103+
console.log(res);
104+
//返回
105+
//[{ status: 'fulfilled', value: 'p1 resolve' },
106+
//{ status: 'rejected', reason: 'p2 reject' },
107+
//{ status: 'fulfilled', value: 'p3 resolve' }]
108+
//当所有的结果都出来时,返回一个数组,里面有各个promise的状态和值组成的对象
109+
})
110+
```
111+
## promise的race or any方法
112+
```
113+
const p1 = new Promise((resolve) => {
114+
setTimeout(() => {
115+
resolve("p1 resolve");
116+
}, 1000);
117+
});
118+
119+
const p2 = new Promise((resolve, reject) => {
120+
setTimeout(() => {
121+
resolve("p1 resolve");
122+
}, 2000);
123+
});
124+
125+
const p3 = new Promise((resolve) => {
126+
setTimeout(() => {
127+
resolve("p1 resolve");
128+
}, 3000);
129+
});
130+
131+
Promise.race([p1,p2,p3]).then(res=>{
132+
console.log(res);
133+
//返回最先执行完的结果
134+
})
135+
136+
Promise.any([p1,p2,p3]).then(res=>{
137+
console.log(res);
138+
//返回最先执行完的resolve
139+
})
140+
```
141+

data/blog/thiszhixiangna?.mdx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: this指向哪?
3+
date: 2023-12-23T12:44:07Z
4+
summary:
5+
tags: []
6+
---
7+
8+
## 显示绑定
9+
在独立调用函数时,this指向调用的当前作用域对象
10+
## 隐式绑定
11+
如果是obj.foo()这样的方式调用obj对象里的函数foo,那么foo的this就会被隐式绑定到obj上
12+
```
13+
var obj = {
14+
name:"你的名字是?"
15+
foo:function(){
16+
console.log(obj.name)
17+
}
18+
bar:function(){
19+
console.log(this.name)
20+
}
21+
}
22+
23+
obj.foo()
24+
obj.bar()
25+
```
26+
this的指向不是在创建时就决定了,而是由执行环境决定的,包括全局环境、对象环境、构造函数环境、事件对象
27+
## apply-call-bind
28+
apply和call可以指定this的绑定对象,他们的第一个参数都为this的指向对象
29+
但传入函数的参数call是逐个传入,而apply是传入一个包含参数的数组
30+
let newFn = fn.bind("aaa")
31+
可以通过bind生成一个新的函数,在调用这个函数时,this指向他的参数
32+
当参数传入一个null或者undfined时,this会被绑定到window上
33+
## new绑定
34+
通过new调用一个函数(构造器时),this指向创建出来的对象
35+
```
36+
function foo(name,age){
37+
this.name= name
38+
this.age = age
39+
}
40+
41+
let fn = new foo("张三",18)
42+
```
43+
## 绑定的优先级
44+
当两个或多个形式的绑定都出现了,那么应该遵从哪一个哪?
45+
经过测试
46+
new绑定>显式绑定>隐式绑定>默认绑定
47+
## 箭头函数
48+
箭头函数没有自己的this,箭头函数使用的this是他parentScope中的this
49+
50+

0 commit comments

Comments
 (0)