0%

连接

默认端口 27017

1
mongo

指定端口 27027

1
mongo --port 27027

连接远程主机上的 MongoDB 实例

1
2
3
4
5
6
mongo "mongodb://mongodb0.example.com:28015"

mongo --host mongodb0.example.com:28015

mongo --host mongodb0.example.com --port 28015

退出

1
quit()

列出数据库

1
show dbs

切换数据库

1
use <database>

列出数据表

1
show tables

查询数据

1
2
3
db.<collection>.find()
db.<collection>.find().count()
db.<collection>.find().pretty()

new Vue 都发生了什么

new vue => init => $mount => compile => render => vnode => patch => DOM

响应式原理

依赖收集

依赖触发

nextTick

如何实现

1
Object.defineProperty()

Virtural Dom

编译原理

对象的属性

属性分两种:数据属性和访问器属性。

数据属性

  1. configurable
  2. enumerable
  3. writable
  4. value

访问器属性

  1. configurable
  2. enumerable
  3. get
  4. set

访问器属性是不能直接定义的,必须使用 Object.defineProperty() 。

es5 与 es6 类的区别

  1. es5 类定义的方法是可枚举的,es6 类定义的方法不可枚举
  2. es5 构造函数可以作为函数单独执行,es6 类不可以单独执行,必须使用 new 关键字
  3. es6 类不存在变量提升(hoist),这一点与 ES5 完全不同。

类的 get 和 set

存值函数和取值函数是设置在属性(访问器属性)的 Descriptor 对象上的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class CustomHTMLElement {
constructor(element) {
this.element = element;
}

get html() {
return this.element.innerHTML;
}

set html(value) {
this.element.innerHTML = value;
}
}

var descriptor = Object.getOwnPropertyDescriptor(
CustomHTMLElement.prototype, "html"
);

"get" in descriptor // true
"set" in descriptor // true

联合类型

Tuple类型

枚举类型

限定数据类型的数组

修饰符

public (default类内、字类和类外都可以访问)

private(类内可以访问)

protected(类内及子类可以访问)

readonly

static (静态属性和方法,可以直接用类名访问)

image-20210311190715485

单例模式 412-2-14

image-20210311192652334

接口 interface

把对象、方法等共性的东西抽象出来

和 type 的区别

readonly

?可选

强校验 412-2-11

class implements interface

接口互相继承 extends

image-20210309210842572

定义函数

image-20210309210744555

抽象类

把多个类共性的东西抽象出来

只能被继承不能被实例化

泛型

约束泛型 (鸭子类型)428-2-14

image-20210309195529784

类的泛型

类型别名

有良好的编程思维,熟悉设计模式

尖端科技

设计模式

享元模式

微信图片_20210223211650

单例模式

image-20210223212534159

工厂模式

jquery

建造者模式

vue / react / express

观察者模式

promise如何解决回调地狱

image-20210224154744243

promise 的状态

一般 Promise 在执行过程中,必然会处于以下几种状态之一。

  1. 待定(pending):初始状态,既没有被完成,也没有被拒绝。

  2. 已完成(fulfilled):操作成功完成。

  3. 已拒绝(rejected):操作失败。

promise 的方法

all

语法: Promise.all(iterable)

参数: 一个可迭代对象,如 Array。

描述: 此方法对于汇总多个 promise 的结果很有用,在 ES6 中可以将多个 Promise.all 异步请求并行操作,返回结果一般有下面两种情况。

  1. 当所有结果成功返回时按照请求顺序返回成功。
  2. 当其中有一个失败方法时,则进入失败方法。

allSettled

Promise.allSettled 的语法及参数跟 Promise.all 类似,其参数接受一个 Promise 的数组,返回一个新的 Promise。唯一的不同在于,执行完之后不会失败,也就是说当 Promise.allSettled 全部处理完成后,我们可以拿到每个 Promise 的状态,而不管其是否处理成功。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const resolved = Promise.resolve(2);

const rejected = Promise.reject(-1);

const allSettledPromise = Promise.allSettled([resolved, rejected]);

allSettledPromise.then(function (results) {

console.log(results);

});

// 返回结果:

// [

// { status: 'fulfilled', value: 2 },

// { status: 'rejected', reason: -1 }

// ]

anny

语法: Promise.any(iterable)

参数: iterable 可迭代的对象,例如 Array。

描述: any 方法返回一个 Promise,只要参数 Promise 实例有一个变成 fulfilled 状态,最后 any 返回的实例就会变成 fulfilled 状态;如果所有参数 Promise 实例都变成 rejected 状态,包装实例就会变成 rejected 状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const resolved = Promise.resolve(2);

const rejected = Promise.reject(-1);

const allSettledPromise = Promise.any([resolved, rejected]);

allSettledPromise.then(function (results) {

console.log(results);

});

// 返回结果:

// 2

race

语法: Promise.race(iterable)

参数: iterable 可迭代的对象,例如 Array。

描述: race 方法返回一个 Promise,只要参数的 Promise 之中有一个实例率先改变状态,则 race 方法的返回状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给 race 方法的回调函数。

我们来看一下这个业务场景,对于图片的加载,特别适合用 race 方法来解决,将图片请求和超时判断放到一起,用 race 来实现图片的超时判断。请看代码片段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//请求某个图片资源

function requestImg(){

var p = new Promise(function(resolve, reject){

var img = new Image();

img.onload = function(){ resolve(img); }

img.src = 'http://www.baidu.com/img/flexible/logo/pc/result.png';

});

return p;

}

//延时函数,用于给请求计时

function timeout(){

var p = new Promise(function(resolve, reject){

setTimeout(function(){ reject('图片请求超时'); }, 5000);

});

return p;

}

Promise.race([requestImg(), timeout()])

.then(function(results){

console.log(results);

})

.catch(function(reason){

console.log(reason);

});

函数式编程将那些跟数据计算无关的操作,都称为 “副效应” (side effect) 。如果函数内部直接包含产生副效应的操作,就不再是纯函数了,我们称之为不纯的函数。
钩子(hook)就是 React 函数组件的副效应解决方案

useState

useEffect

第一个参数是一个函数
第二个参数是一个数组(数组里的有一项变化就执行)(两个特例,1,不传。2,传一个空数组)

useEffect()的作用就是指定一个副效应函数,组件每渲染一次,该函数就自动执行一次。组件首次在网页 DOM 加载后,副效应函数也会执行。

  1. 提高了代码复用(不用在mount和update里都写一遍函数)
  2. 优化了关注点分离(业务逻辑都在各自的useEffect里,互不干扰)

只要是副效应,都可以使用useEffect()引入。它的常见用途有下面几种。

  1. 获取数据(data fetching)
  2. 事件监听或订阅(setting up a subscription)
  3. 改变 DOM(changing the DOM)
  4. 输出日志(logging)

    副作用调用时机

参考:
http://www.ruanyifeng.com/blog/2020/09/react-hooks-useeffect-tutorial.html

浅拷贝

object.assign

扩展运算符

concat (数组)

sblice (数组)

深拷贝

JSON.stringfy()

手写递归实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
let obj1 = {
a: {
b: 1,
},
};

function deepClone(obj) {
let cloneObj = Array.isArray(obj) ? [] : {};

for (let key in obj) {
//遍历

if (typeof obj[key] === "object") {
cloneObj[key] = deepClone(obj[key]); //是对象就再次调用该函数递归
} else {
cloneObj[key] = obj[key]; //基本类型的话直接复制值
}
}

return cloneObj;
}

let obj2 = deepClone(obj1);

obj1.a.b = 2;

console.log(obj2); // {a:{b:1}}

改进后递归实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
const isComplexDataType = (obj) =>
(typeof obj === "object" || typeof obj === "function") && obj !== null;

const deepClone = function (obj, hash = new WeakMap()) {
if (obj.constructor === Date) return new Date(obj); // 日期对象直接返回一个新的日期对象

if (obj.constructor === RegExp) return new RegExp(obj); //正则对象直接返回一个新的正则对象

//如果循环引用了就用 weakMap 来解决

if (hash.has(obj)) return hash.get(obj);

let allDesc = Object.getOwnPropertyDescriptors(obj);

//遍历传入参数所有键的特性

let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc);

//继承原型链

hash.set(obj, cloneObj);

for (let key of Reflect.ownKeys(obj)) {
cloneObj[key] =
isComplexDataType(obj[key]) && typeof obj[key] !== "function"
? deepClone(obj[key], hash)
: obj[key];
}

return cloneObj;
};

// 下面是验证代码

let obj = {
num: 0,

str: "",

boolean: true,

unf: undefined,

nul: null,

obj: { name: "我是一个对象", id: 1 },

arr: [0, 1, 2],

func: function () {
console.log("我是一个函数");
},

date: new Date(0),

reg: new RegExp("/我是一个正则/ig"),

[Symbol("1")]: 1,
};

Object.defineProperty(obj, "innumerable", {
enumerable: false,
value: "不可枚举属性",
});

obj = Object.create(obj, Object.getOwnPropertyDescriptors(obj));

obj.loop = obj; // 设置loop成循环引用的属性

let cloneObj = deepClone(obj);

cloneObj.arr.push(4);

console.log("obj", obj);

console.log("cloneObj", cloneObj);