手写题 实现 Promise.all 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 static all (promiseArr ) { let result = []; let count = 0 ; return new Mypromise ((resolve, reject ) => { for (let i = 0 ; i < promiseArr.length ; i++) { Promise .resolve (promiseArr[i]).then ( (res ) => { result[i] = res; count++; if (count === promiseArr.length ) { resolve (result); } }, (err ) => { reject (err); } ); } }); }
实现 Promise.finally 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Promise .prototype .finally = function (callback ) { return this .then ( (value ) => { return Promise .resolve (callback ()).then (() => { return value; }); }, (err ) => { return Promise .resolve (callback ()).then (() => { throw err; }); } ); };
实现 Promise.allSettled 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 Promise .allSettled = function (promiseArr ) { let result = []; return new Promise ((resolve, reject ) => { promiseArr.forEach ((p, i ) => { Promise .resolve (p).then ( (val ) => { result.push ({ status : "fulfilled" , value : val, }); if (result.length === promiseArr.length ) { resolve (result); } }, (err ) => { result.push ({ status : "rejected" , reason : err, }); if (result.length === promiseArr.length ) { resolve (result); } } ); }); }); };
实现 Promise.race 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 static race (promiseArr ) { return new Mypromise ((resolve, reject ) => { for (let i = 0 ; i < promiseArr.length ; i++) { Promise .resolve (promiseArr[i]).then ( (res ) => { resolve (res); }, (err ) => { reject (err); } ); } }); } }
数组去重 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function uniq (arr ) { return arr.reduce ((prev, next ) => { if (!prev.includes (next)) { prev.push (next); } return prev; }, []); }console .log (uniq (arr));function unq (arr ) { return arr.reduce ((prev, next ) => { if (!prev.includes (next)) { prev.push (next); } return prev; }, []); }
数组扁平化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function flot (arr ) { let result = []; for (let i = 0 ; i < arr.length ; i++) { if (Array .isArray (arr[i])) { result = result.concat (flot (arr[i])); } else { retult = result.push (arr[i]); } } return result; }function flot (arr ) { return arr.reduce ((prev, next ) => { return prev.concat (Array .isArray (next) ? flat (next) : next); }, []); }
实现es6
数组的forEach
方法 1 2 3 4 5 6 Array .prototype .myForEach = function (fn ) { let arr = [...this ]; for (let i = 0 ; i < arr.length ; i++) { fn (arr[i], i, arr); } };
实现es6
数组的filter
方法 1 2 3 4 5 6 7 8 9 10 Array .prototype .myFilter (fn ) { let arr = [...this ]; let newArr = []; for (let i=0 ; i<arr.length ; i++) { if (fn (arr[i], i, arr)) { newArr.push (arr[i]); } } return newArr; }
实现es6
数组的reduce
方法 1 2 3 4 5 6 7 8 9 10 11 12 13 Array .prototype .myReduce = function (fn, params ) { let arr = [...this ]; let index = 0 ; let prev = params; if (!params) { index = 1 ; prev = arr[0 ]; } for (let i = 0 ; i < arr.length ; i++) { prev = fn (prev, arr[i], i, arr); } return prev; };
实现es6
数组的map
方法 1 2 3 4 5 6 7 8 Array .prototype .myMap (fn ) { let arr = [...this ]; let newArr = []; for (let i=0 ; i<arr.length ; i++) { newArr.push (fn (arr[i], i, arr)); } return newArr; }
实现es6
数组的find
方法 1 2 3 4 5 6 7 8 Array .prototype .myFind (fn ) { let arr = [...this ]; for (let i=0 ; i<arr.length ; i++) { if (fn (arr[i], i, arr)) { return arr[i]; } } }
实现es6
数组的findIndex
方法 1 2 3 4 5 6 7 8 9 Array .prototype .myFindIndex = function (fn ) { let arr = [...this ]; for (let i = 0 ; i < arr.length ; i++) { if (fn (arr[i], i, arr)) { return i; } } return -1 ; };
实现es6
数组的every
方法 1 2 3 4 5 6 7 8 9 Array .prototype .myEvery = function (fn ) { let arr = [...this ]; for (let i=0 ; i<arr.length ; i++) { if (!fn (arr[i], i, arr)){ return false } } return true ; }
实现es6
数组的some
方法 1 2 3 4 5 6 7 8 9 Array .prototype .mySome = function (fn ) { let arr = [...this ]; for (let i=0 ; i<arr.length ; i++) { if (fn (arr[i], i, arr)) { return true } } return false ; }
实现es6
数组的includes
方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Array .prototype .myIncludes = function (value, index ) { let arr = [...this ]; let fIndex = 0 ; if (index !== undefined && typeof index === 'number' && !isNaN && index !== Infinity ) fIndex = index; if (fIndex < 0 ) fIndex = arr.length +fIndex; for (let i=fIndex; i<arr.length ; i++) { if (Object .is (arr[i], value)) { return true ; } } return false ; }
实现es6
数组的flat
方法 1 2 3 4 5 6 7 8 9 10 11 Array .prototype .myFlat = function (value = 1 ) { let arr = [...this ]; if (value === 0 ) return arr; if (typeof value !== "number" || isNaN (value)) value = 1 ; return arr.reduce ((prev, next ) => { if (Array .isArray (next)) { return [...prev, ...next.myFlat (value-1 )]; } return [...prev, next]; }) }
实现防抖 debounce 1 2 3 4 5 6 7 8 9 10 11 12 function debounce (fn, time ) { let timer = null ; return function ( ) { if (!timer) { clearInterval (timer); } timer = setTimeout (() => { fn.apply (this , arguments ); }, time); }; }
实现节流函数 throttle 1 2 3 4 5 6 7 8 9 10 function throttle (fn, time ) { let date = 0 ; return function ( ) { let newDate = new Date ().getTime (); if (newDate - date > time) { fn.apply (this , arguments ); date = newDate; } }; }
写一个完整的深拷贝 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function deepClone (obj ) { let newObj = obj instancef Array ? [] : {} if (obj && typeof obj === "object" ) { for (const key in obj) { if (obj.hasOwnProperty (key)) { if (obj[key] && typeof obj[key] === 'object' ) { newObj[key] = deepClone (obj[key]) } else { newObj[key] = obj[key] } } } } return newObj } let a = [1 , 2 , 3 , 4 , 5 ] let b = deepClone (a) a[0 ] = 2 console .log (a, b);
实现 new 关键字编写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function objectFactory ( ) { var obj = new Object (); Constructor = Array .prototype .shift .call (arguments ); obj.__proto__ = Constructor .prototype ; var ret = Constructor .apply (obj, arguments ); return typeof ret === "object" ? ret || obj : obj; }function person (name, age ) { this .name = name; this .age = age; }let p = objectFactory (person, "布兰" , 12 );console .log (p);
Es5 实现继承&Es6 实现继承 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 function Animal ( ) { this .colors = ["black" , "white" ]; }Animal .prototype .getColor = function ( ) { return this .colors ; };function Dog ( ) {}Dog .prototype = new Animal ();let dog1 = new Dog (); dog1.colors .push ("brown" );let dog2 = new Dog ();console .log (dog2.colors ); function Animal (name ) { this .name = name; this .colors = ["black" , "white" ]; }Animal .prototype .getName = function ( ) { return this .name ; };function Dog (name, age ) { Animal .call (this , name); this .age = age; }Dog .prototype = new Animal ();Dog .prototype .constructor = Dog ;let dog1 = new Dog ("奶昔" , 2 ); dog1.colors .push ("brown" );let dog2 = new Dog ("哈赤" , 1 );console .log (dog2);function Animal (name ) { this .name = name; this .getName = function ( ) { return this .name ; }; }function Dog (name ) { Animal .call (this , name); }Dog .prototype = new Animal ();function object (o ) { function F ( ) {} F.prototype = o; return new F (); }function inheritPrototype (child, parent ) { let prototype = object (parent.prototype ); prototype.constructor = child; child.prototype = prototype; }inheritPrototype (Dog , Animal );class Animal { constructor (name ) { this .name = name; } getName ( ) { return this .name ; } }class Dog extends Animal { constructor (name, age ) { super (name); this .age = age; } }
手写 Call 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 function Person ( ) { console .log (this .name , a, b, c, d); }let egg = { name : "小雅" , };Function .prototype .mycall = function (obj ) { obj = obj || window ; let newArgs = []; obj.fn = this ; for (let i = 1 ; i < arguments .length ; i++) { newArgs.push (`arguments[${i} ]` ); } let res = eval (`obj.fn(${newArgs} )` ); delete obj.fn ; return res; };console .log (Person .mycall (egg, {}, 2 , 3 , 4 ));Person .call (egg, {}, 2 , 3 , 4 );Function .prototype .mycall = function (obj ) { obj = obj || window ; obj.fn = this ; delete obj.fn ; };
手写 Apply 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 function Person (a, b ) { console .log (this .name , a, b); }let egg = { name : "小雅" , };Function .prototype .myapply = function (obj, args ) { obj = obj || window ; let newArgs = []; let res = null ; obj.fn = this ; if (!args) { res = obj.fn (); } else { for (let i = 0 ; i < args.length ; i++) { newArgs.push (`args[${i} ]` ); } res = eval (`obj.fn(${newArgs} )` ); } delete obj.fn ; return res; };Person .myapply (egg, [1 , "2" ]);Person .apply (egg, [1 , "2" ]);
手写 bind 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function Person (a, b ) { console .log (this .name , a, b); }let egg = { name : "小雅" , };Function .prototype .mybind = function (obj ) { let args = Array .prototype .slice .call (arguments , 1 ); let arg = null ; console .log (this ); let that = this ; return function ( ) { console .log (this ); arg = Array .prototype .slice .call (arguments ); that.apply (obj, [...args, ...arg]); }; };Person .mybind (egg, 1 )(2 );
实现柯里化函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 function curry (fn, currArgs ) { return function ( ) { let args = Array .prototype .slice .call (arguments ); console .log (fn, currArgs); if (currArgs) { args = args.concat (currArgs); } if (args.length < fn.length ) { return curry (fn, args); } console .log (args); return fn.apply (this , args); }; }function sum (a, b, c, d, e ) { return a + b + c + d + e; }const fn = curry (sum);console .log (fn (1 )(2 )(3 )(4 )(5 )); console .log (fn (1 )(2 , 3 )(4 , 5 )); console .log (fn (1 , 2 , 3 , 4 , 5 ));
实现 jsonp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const jsonp = ({ url, params, callbackName } ) => { const generateUrl = ( ) => { let dataSrc = "" ; for (let key in params) { if (params.hasOwnProperty (key)) { dataSrc += `${key} =${params[key]} &` ; } } dataSrc += `callback=${callbackName} ` ; return `${url} ?${dataSrc} ` ; }; return new Promise ((resolve, reject ) => { const scriptEle = document .createElement ("script" ); scriptEle.src = generateUrl (); document .body .appendChild (scriptEle); window [callbackName] = (data ) => { resolve (data); document .removeChild (scriptEle); }; }); };
实现 instanceOf 1 2 3 4 5 6 7 8 9 10 function instanceOf (left, right ) { let proto = left.__proto__ ; while (true ) { if (proto === null ) return false ; if (proto === right.prototype ) { return true ; } proto = proto.__proto__ ; } }
图片懒加载,实现lazyLoad()
这个方法,使之只显示当前屏幕图片并测试 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 let imgSrc = [ "./image/01.jpg" , "./image/02.jpg" , "./image/03.jpg" , "./image/04.jpg" , "./image/05.jpg" , "./image/06.jpg" , "./image/07.jpg" , "./image/08.jpg" , "./image/09.jpg" , "./image/10.jpg" , "./image/11.jpeg" , "./image/12.jpeg" , "./image/13.jpeg" , "./image/14.jpeg" , "./image/15.jpeg" , "./image/16.jpeg" , "./image/17.jpeg" , "./image/18.jpeg" , "./image/19.jpeg" , "./image/20.jpeg" ];let image = document .getElementById ('image' );let imgs = [...image.children ];for (let i=0 ; i<imgs.length ; i++) { imgs[i].dataset .src = imgSrc[i]; }let len = imgs.length ;const lazyLoad = (function ( ) { return function ( ) { let deleteIndex = []; for (let i=0 ; i<imgs.length ; i++) { if (imgs[i].getBoundingClientRect ().top < window .innerHeight ) { imgs[i].src = imgs[i].dataset .src ; deleteIndex.push (i) } } imgs = imgs.filter ((item, index ) => { return !deleteIndex.includes (index) }) if (imgs.length === 0 ) { document .removeEventListener ('scroll' , lazyLoad); } } })()lazyLoad ();document .addEventListener ('scroll' , lazyLoad);
栈 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 class Stack { contructor ( ) { this .stack = []; } toString ( ) { return this .stack .join (); } push (val ) { this .stack .push (val); } pop ( ) { return this .stack .pop (); } top ( ) { return this .stack [this .stack .length -1 ]; } size ( ) { return this .stack .length ; } }
队列 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 class Queue { constructor (size = 10 ) { this .queue = []; this .size = size; } enQueue (val ) { if (this .isFull ()) { this .deQueue (); } this .queue .push (val) } deQueue ( ) { return this .queue .shift (); } isFull ( ) { return this .queue .length === this .size ; } isEmpty ( ) { return this .queue .length === 0 ; } toString ( ) { return this .queue .join (); } }
链表 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 class Node { constructor ({val, next} ) { this .val = val; this .next = next; } }let _head = Symbol ('_head' );class NodeList { constructor ( ) { Object .defineProperty (this , { [_head]:{ writable : true , value : new Node ({val : null , next : null }), enumerable :false , configurable : false } }) } insert (val, index ) { let node = new Node ({val : val, next : null }) if (!this [_head].val ) { this [_head] = node; return ; } if (!index) { let lastNode = this .find (this .size ()-1 ); lastNode.next = node; return ; } if (index === 0 ) { node.next = this [_head]; this [_head] = node; return ; } let prevNode = this .find (index-1 ); node.next = prevNode.next ; prevNode.next = node; return ; } size ( ) { let i=0 ; let n = this [_head]; while (n) { n = n.next ; i++; } return i; } toString ( ) { let n = this [_head]; let str = "" ; while (n){ str += n.val ; if (n.next ) { str += ", " } n = n.next ; } return str; } find (index ) { let n = this [_head]; let i = 0 ; while (i !== index) { i++; n = n.next ; } return n; } toArray ( ) { let n = this [_head]; let arr = []; while (n) { arr.push (n.val ); n = n.next ; } return arr; } update (val, index ) { let node = this .find (index); node.val = val; } deleteByIndex (index ) { let node = this .find (index); if (index === 0 ) { this [_head] = node.next ; node.next = null ; return ; } let prevNode = this .find (index-1 ); prevNode.next = node.next ; node.next = null ; } }
树 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 class Tree { constructor (val, left, right ) { this .val = val; this .left = left; this .right = right; } }let head = new Tree (1 , null , null );let node_1 = new Tree (2 , null , null );let node_2 = new Tree (3 , null , null );let node_3 = new Tree (4 , null , null );let node_4 = new Tree (5 , null , null );let node_5 = new Tree (6 , null , null );let node_6 = new Tree (7 , null , null ); head.left = node_1; head.right = node_2; node_1.left = node_3; node_1.right = node_4; node_2.left = node_5; node_2.right = node_6; node_3.left = node_7;function inOrder (head ) { if (!head) return let stack = [head]; let n = head.left ; while (stack.length ) { while (n) { stack.push (n); n = n.left ; } let node = stack.pop (); console .log (node.val ); if (node.right ) { stack.push (node.right ); n = node.right .left ; } } }function prevOrder (head ) { if (!head) return let stack = [head]; while (stack.length ) { let n = stack.pop (); console .log (n.val ); n.right && stack.push (n.right ); n.left && stack.push (n.left ); } }function order (head ) { if (!head) return let queue = [head]; while (queue.length ) { let n = queue.shift (); console .log (n.val ); n.left && queue.push (n.left ); n.right && queue.push (n.right ); } }