深拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function deepClone<T extends Array<T> | any>(obj: T): T { if (typeof obj !== "object" || obj === null) { return obj; } if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj);
const result: T = new obj.constructor();
for (const key in obj) { if (obj.hasOwnProperty(key)) { result[key] = deepClone(obj[key]); } } return result; }
|
Promise
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
| const PROMISE_STATUS_PENDING = "pending"; const PROMISE_STATUS_FULFILLED = "fulfilled"; const PROMISE_STATUS_REJECTED = "rejected";
class MyPromise { constructor(executor) { this.status = PROMISE_STATUS_PENDING; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = [];
const resolve = value => { if (this.status === PROMISE_STATUS_PENDING) { queueMicrotask(() => { if (this.status !== PROMISE_STATUS_FULFILLED) return; this.status = PROMISE_STATUS_FULFILLED; this.value = value; this.onResolvedCallbacks.forEach(fn => { fn(this.value) }); }); } };
const reject = value => { if (this.status === PROMISE_STATUS_PENDING) { queueMicrotask(() => { if (this.status !== PROMISE_STATUS_REJECTED) return; this.status = PROMISE_STATUS_REJECTED; this.reason = reason; this.onRejectedCallbacks.forEach(fn => { fn(this.reason) }); }); } };
try { executor(resolve, reject); } catch (error) { reject(error); } }
static resolve(value) { return new MyPromise(resolve => resolve(value)); }
static reject(reason) { return new MyPromise((resolve, reject) => reject(reason)); }
then(onFulfilled, onRejected) { onFulfilled = onFulfilled || (value => { return value; }); onRejected = onRejected || (err => { throw err; });
return new myPromise((resolve, reject) => { if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) { execFunctionWithCatchError(onFulfilled, this.value, resolve, reject); } if (this.status === PROMISE_STATUS_REJECTED && onRejected) { execFunctionWithCatchError(onRejected, this.reason, resolve, reject); }
if (this.status === PROMISE_STATUS_PENDING) { if (onFulfilled) { this.onFulfilledFns.push(() => { execFunctionWithCatchError(onFulfilled, this.value, resolve, reject); }); } if (onRejected) { this.onRejectedFns.push(() => { execFunctionWithCatchError(onRejected, this.reason, resolve, reject); }); } } }) }
catch(onRejected) { return this.then(undefined, onRejected); } finally(onFinally) { this.then(() => { onFinally() }, () => { onFinally() }) }
static all(promises) { return new myPromise((resolve, reject) => { const values = []; promises.forEach(promise => { promise.then( res => { values.push(res); if (values.length === promise.length) { resolve(values); } }, err => { reject(err) } ); }); }); }
static race(promises) { return new myPromise((resolve, reject) => { promises.forEach(promise => { promise.then( res => { resolve(res); }, err => { reject(err); } ) }) }); }
static any(promises) { return new myPromise((resolve, reject) => { const reasons = []; promises.forEach(promise => { promise.then( res => { resolve(res); }, err => { reasons.push(err) if(reasons.length === promises.length) { reject(reasons) } } ) }) }) } }
|
防抖和节流
1 2 3 4 5 6 7 8 9 10 11 12
| function debounce(fn: Function, delay: number) { let timer: any = null; return function() { if(timer) { clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, arguments) timer = null; }, delay) }; }
|
1 2 3 4 5 6 7 8 9 10
| function throttle(fn: Function, delay: number) { let timer: any = null; return function () { if(timer) return; timer = setTimeout(() => { fn.apply(this, arguments); timer = null }, delay) }; }
|
快速排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function quickSort(arr: number[], startIndex: number = 0): number[] { if (arr.length <= 1) return arr; const right: number[] = []; const left: number[] = []; const startNum = arr.splice(startIndex, 1)[0]; for(let i = 0; i < arr.length; i++) { if(arr[i] < startNum) { left.push(arr[i]); } else [ right.push(arr[i]); ] } return [...qucikSort(left), startNum, ...qucikSort(right)]; }
|
输入为两个一维数组,将这两个数组合并,去重,不要求排序,返回一维数组
1 2 3
| function dealArr(arr1: any[], arr2: any[]): any[] { return Array.from(new Set([...arr1, ...arr2])) }
|
编写函数convert(money) ,传入金额,将金额转换为千分位表示法。ex:-87654.3 => -87,654.3
思路:判断是否是负数,判断是否有小数点,将整数部分进行处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function convert(money: number): number { let result: string = ''; let negativeFlag: string = '' let tail: string = ''; let arr: string[] = [...String(money)];
if(arr[0] === '-') { negativeFlag = '-' arr.shift() }
const dotIndex: number = arr.indexOf("."); if (dotIndex !== -1) { tail = arr.splice(dotIndex, arr.length - dotIndex).join(""); }
result: string = arr.join("").replace(/(?!^)(?=(\d{3})$)/g, ','); return negativeFlag + result + tail; }
|