Map 1.回调函数的参数、返回值 map的参数:当前值、index、原始数组。 map可以通过第三个传递值(原始数组的引用)更改原始数组
1 2 3 4 5 6 7 8 9 10 11 Array .prototype .MyMap = function (fn, context ) { let arr = Array .from (this ) const result = [] for (let i = 0 ; i < arr.length ; i++) { result.push (fn.call (context, arr[i], i, this )) } return result }
Reduce 和map一样,可以通过原始数组this更改原始数组
1 2 3 4 5 6 7 8 9 Array .prototype .MyReduce = function (fn, initValue ) { const arr = Array .from (this ) let res = initValue ? initValue : arr[0 ] const startIndex = initValue ? 0 : 1 for (let i = startIndex; i < arr.length ; i++) { res = fn.call (null , res, arr[i], i, this ) } return res }
call/apply 1 2 3 4 5 6 7 8 9 Function .prototype .MyCall = function (context = window , ...args ) { const fn = this const key = Symbol ("fn" ) context[key] = fn const res = context[fn](...args) delete context[key] return res }
bind 1 2 3 4 5 6 7 8 9 10 Function .prototype .myBind = function (context, ...args ) { const fn = this ; return function (...newArgs ) { return fn.apply (context, [...args, ...newArgs]); }; };
Object.create 创建一个原型为proto的对象
1 2 3 4 5 6 7 8 9 function create (proto ) { function F ( ) { } F.prototype = proto F.prototype .constructor = F return new F () }
New关键字 1 2 3 4 5 6 const MyNew = (constructor, ...args ) => { const instance = Object .create (constructor.prototype ) const res = constructor.apply (instance, args) return typeof res === 'object' ? res : instance }
instance关键字 按照原型链向上查找,如果instance的原型是constructor的prototype,那么就是
1 2 3 4 5 6 7 8 const MyInstance = (instance, constructor ) => { let proto = Object .getPrototypeOf (instance) while (true ) { if (proto === null ) return false if (proto === constructor.prototype ) return true proto = Object .getPrototypeOf (proto) } }
单例模式 使用proxy进行代理proxy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const proxy = (func ) => { let instance let handler = { constructor (target, argumentList, newTarget ) { if (!instance) { instance = Reflect .construct (target, argumentList, newTarget) } return instance } } return new Proxy (func, handler) }
深拷贝 考虑循环引用以及Array、正则、Date等情况
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 function deepClone (obj, hash = new WeakMap () ) { if (obj === null || typeof obj !== 'object' ) { return obj; } if (hash.has (obj)) { return hash.get (obj); } if (obj instanceof Date ) { return new Date (obj); } if (obj instanceof RegExp ) { return new RegExp (obj.source , obj.flags ); } if (obj instanceof Function ) { return obj; } if (obj instanceof Map ) { const mapClone = new Map (); hash.set (obj, mapClone); obj.forEach ((value, key ) => { mapClone.set (deepClone (key, hash), deepClone (value, hash)); }); return mapClone; } if (obj instanceof Set ) { const setClone = new Set (); hash.set (obj, setClone); obj.forEach (value => { setClone.add (deepClone (value, hash)); }); return setClone; } const clone = Array .isArray (obj) ? [] : Object .create (Object .getPrototypeOf (obj)); hash.set (obj, clone); const symbolKeys = Object .getOwnPropertySymbols (obj); symbolKeys.forEach (symKey => { clone[symKey] = deepClone (obj[symKey], hash); }); const keys = Object .keys (obj); keys.forEach (key => { clone[key] = deepClone (obj[key], hash); }); return clone; }