🏈 [手写代码] EcmaScript API
call/apply/bind
typescriptCopy
/**
* 手写call
*/
(Function.prototype as any).myCall = function (context: any, ...rest: any[]) {
const fn = this // this指向 Person.prototype.say
const symbol = Symbol(this)
context[symbol] = fn // 将fn绑定到context对象下,此时say的this会指向context
context[symbol](...rest)
delete context[symbol]
}
class Person {
// 年龄
public age = 18
constructor(age: number) {
this.age = age
}
// 方法
public say(): void {
console.log(this.age);
};
}
const person1 = new Person(1)
const person2 = new Person(2);
(person1.say as any).myCall(person2) // 2sleep/delay
typescriptCopy
const sleep = (seconds: number) => new Promise((resolve) => setTimeout(resolve, seconds))
const delay = (fun: Function, seconds: number, ...args: any[]) => new Promise((resolve) => setTimeout(() => {
fun(...args)
resolve(1)
}, seconds))
console.log('run');
sleep(3000).then(() => {
console.log('finished sleep');
})
delay((data: number) => { console.log(data) }, 3000, 10).then(() => {
console.log('finished delay');
})
// 输出
// run
// finished sleep
// 10
// finished delayPromise.all
typescriptCopy
// 继发版本
(Promise.prototype as any).myAll = async function (values: any[]): Promise<any[]> {
const result = []
for (let index = 0; index < values.length; index++) {
// 异步出错等同于被Promise rejct
result.push(await values[index])
}
return result
}
// 并发版本
(Promise.prototype as any).myAll = async function (values: any[]): Promise<any[]> {
const result: any[] = []
const p = values.map(async (ele, index) => {
result.push(await ele)
})
for (const iterator of p) {
await iterator
}
return result
}
const promise1 = new Promise((resolve) => setTimeout(() => {
resolve("promise1")
console.log("promise1");
}, 1000))
const promise2 = new Promise((resolve, reject) => setTimeout(() => {
reject("promise2")
console.log("promise2");
}, 2000));
(Promise.prototype as any).myAll([promise1, promise2]).then((data: any) => {
console.log({ ...data });
}).catch((err: any) => {
console.log('err', err);
})
// 输出
// promise1
// promise2
// err promise2isArray
typescriptCopy
(Array.prototype as any).myIsArray = function (obj: any) {
// return typeof obj === 'object' && obj instanceof Array
return Object.prototype.toString.call(obj) === '[object Array]'
}flat
typescriptCopy
function flat(data: any[], dept: number = 0): any[] {
if (dept === 0) return data
return data.reduce((pre: any[], current) => {
// let a = [0]
// a.concat([1,2,3]) -> [0 ,1, 2, 3]
return pre.concat(Array.isArray(current) ? flat(current, dept - 1) : current)
}, [])
}
console.log(flat([1, 2, [3, 4], 1], 1));
trim
typescriptCopy
(String.prototype as any).myTrim = function () {
const str = this;
return str.replace(/^\s+|\s+$/g, '')
};
console.log((' 23 ' as any).myTrim());
