思路:f(n) 的值永远都是 f(n-1) 的结果 里面每一项push ()
export function generateParenthesis(initn: number): string[] {
const func = (n: number): string[] => {
if (n == 1) {
return ['()']
}
let res = func(n - 1)
let pjRes = []
for (let i = 0; i < res.length; i++) {
let str = res[i]
let sL = str.length
for (let j = 0; j < sL; j++) {
pjRes.push(`${str.slice(0, j)}()${str.slice(j, sL)}`)
}
}
return pjRes
}
return Array.from(new Set(func(initn)))
}
console.log(generateParenthesis(3), 'na');
export function cloneDeep(obj: any, map = new WeakMap()): any {
if (typeof obj !== 'object' || obj == null) return obj
// 避免循环引用
const objFromMap = map.get(obj)
if (objFromMap) return objFromMap
let target: any = {}
map.set(obj, target)
// Map
if (obj instanceof Map) {
target = new Map()
obj.forEach((v, k) => {
const v1 = cloneDeep(v, map)
const k1 = cloneDeep(k, map)
target.set(k1, v1)
})
}
// Set
if (obj instanceof Set) {
target = new Set()
obj.forEach(v => {
const v1 = cloneDeep(v, map)
target.add(v1)
})
}
// Array
if (obj instanceof Array) {
target = obj.map(item => cloneDeep(item, map))
}
// Object
for (const key in obj) {
const val = obj[key]
const val1 = cloneDeep(val, map)
target[key] = val1
}
return target
}
const a: any = {
set: new Set([1, 2, 3, 4]),
map: new Map([['x', 10], ['y', 20]]),
info: {
city: '北京'
},
fn: () => { },
}
a.self = a
console.log(cloneDeep(a), 'cloneDeep');
上面代码相当于
['1', '2', '3'].map((item, index) => {
parseInt(item, index)
// parseInt
// 转换的数字
// raIndex 第二个参数是 进制 单位 (2-32)
/**
* parInt('1', 0) // 0 的时候 说明没传 是2进制
* parInt('2', 1) // 1 的时候 没有 1 进制 所以返回 NAN
* parInt('3', 2) // 2 的时候 3 不属于二进制的内容(011101010101010这种只有 0 和 1 才属于二进制)
*/
})
所以最终返回 [1, NaN, NaN]
const fn = (x, y) => {
// 这里就相当于 x = num; y = obj
}
let num = 'aaa'
let obj = { name: 'glack' }
fn(num, obj)
const arr1 = [
{ id: 1, name: '部门A', parent_id: 0 },
{ id: 2, name: '部门B', parent_id: 1 },
{ id: 3, name: '部门C', parent_id: 1 },
{ id: 4, name: '部门D', parent_id: 2 },
{ id: 5, name: '部门E', parent_id: 4 },
{ id: 6, name: '部门F', parent_id: 4 },
];
/**
* 针对有序的二维数组排列树节点
* @param arr arr
*/
interface ITreeNode {
id: number,
name: string,
children?: ITreeNode[]
}
interface ITreeItem {
id: number,
name: string,
parent_id: number
}
export const treeTransform = (arr: ITreeItem[]): ITreeNode | null => {
// 用于id 和 treeNode 的映射
let treeMap: Map<number, ITreeNode> = new Map()
let root: ITreeNode | null = null
// 定义tree node 并加入 map
arr.forEach(({ id, name }) => {
const treeNode: ITreeNode = { id, name }
treeMap.set(id, treeNode)
})
arr.forEach(item => {
const { id, parent_id } = item
const treeNode = treeMap.get(id)
// 找到 parentNode 并加入到它的 children
const parentNode = treeMap.get(parent_id)
if (parentNode && treeNode) {
if (parentNode.children == null) parentNode.children = []
parentNode.children.push(treeNode)
}
// console.log(parentNode, 'parentNode');
// console.log(treeNode, 'treeNode');
// 找到根节点
if (parent_id === 0) {
// @ts-ignore
root = treeNode
}
})
return root
}
let result = treeTransform(arr1)
console.log(result);
let map = new Map();
map.set('arr', []);
let arr = map.get('arr');
arr.push('a');
map.get('arr') // ['a']
let res: any[] = []
let treeTransformArray = (root: any[], parent_id: number = 0) => {
let arr = Array.isArray(root) ? root : [root]
// 遍历所有元素
arr.forEach(item => {
if (item.children) {
treeTransformArray(item.children, item.id)
}
res.push({ id: item.id, name: item.name, parent_id })
})
}
// @ts-ignore 这里的result 是上面的结果
treeTransformArray(result)
console.log(res, 'zz');
function Foo(){
Foo.a = function name() {
console.log(1);
}
this.a = function () {
console.log(2);
}
}
Foo.prototype.a = function(){ console.log(3); }
Foo.a = function(){ console.log(4) }
Foo.a()
let obj = new Foo()
obj.a()
Foo.a()
// 4 2 1
Promise.resolve().then(() => {
console.log(1)
}).then(() => {
console.log(2)
}).then(() => {
console.log(3)
}).then(() => {
console.log(4)
}).then(() => {
console.log(5)
}).then(() => {
console.log(6)
})
Promise.resolve().then(() => {
console.log(10)
}).then(() => {
console.log(20)
}).then(() => {
console.log(30)
}).then(() => {
console.log(40)
}).then(() => {
console.log(50)
}).then(() => {
console.log(60)
})
// 1 10 2 20 3 30 4 40 5 50 6 60
多个promise 已完成的状态同时执行 .then 的链式调用
所以 .then会交替执行
Promise.resolve().then(() => {
console.log(1)
return Promise.resolve(100)
}).then((res) => {
console.log(res)
}).then(() => {
console.log(3)
}).then(() => {
console.log(4)
}).then(() => {
console.log(5)
}).then(() => {
console.log(6)
})
Promise.resolve().then(() => {
console.log(10)
}).then(() => {
console.log(20)
}).then(() => {
console.log(30)
}).then(() => {
console.log(40)
}).then(() => {
console.log(50)
}).then(() => {
console.log(60)
})
// 1 10 20 30 100 40 3 50 4 60 5 6
.then 中返回promise 实例会慢两拍(三步) 因为需要时间把自己 penging 变成 fulfilled状态
didMount(){
// 假设默认值是 0
this.setState({
val: this.state.val + 1
})
console.log(this.state.val) // 异步更新 0
this.setState({
val: this.state.val + 1
})
console.log(this.state.val) // 异步更新 0
setTimeout(() => {
this.setState({
val: this.state.val + 1
})
console.log(this.state.val) // 同步更新 2
this.setState({
val: this.state.val + 1
})
console.log(this.state.val) // 同步更新 3
})
}
如果同时多个setState 都要修改val 那么会优先使用 下面的哪个setState语句
传入函数: this.setState((prev, props) => { return …})
setState 同步更新:在setTimeout setInterval promise.then
自定义的 dom 事件
ajax 回调
例子:
document.getElementById('id').addEventlistener('click', () => {
this.setState({
val: this.state.val + 1
})
console.log(this.state.val) // 同步更新
})
setState是同步 不过只不过是当做异步处理
可以在setTimeout 中 异步更新了
Auto Batch
需要将 ReactDOM.render 替换为 ReactDOM.createRoot
let a = { n: 1 }
let b = a
a.x = a = { n: 2 }
console.log(a.x) // undefined
console.log(b.x) // n: 2
let a = {}, b = '123', c = 123
a[b] = 'b'
a[c] = 'c'
// log => a[b] c
let a = {}, b = Symbol('123'), c = Symbol('123')
a[b] = 'b'
a[c] = 'c'
// log => a[b] b
SPA 特点
MPA