2024秋招大厂前端算法手撕101道
1.手写Object.create
function myCreate ( obj ) {
function F ( ) {
}
F . prototype= obj
return new F ( )
}
var obj= {
x : 10 }
var newObj= myCreate ( obj)
console. log ( newObj. __proto__)
2.手写instanceof方法
function myInstanceof ( left, right ) {
if ( typeof right!== 'function' || ! right. prototype) throw new Error ( 'type error' )
if ( Object ( left) !== left) return false
let proto= Object. getPrototypeOf ( left)
let prototype= right. prototype
while ( true ) {
if ( ! proto) return false
if ( proto== prototype) return true
proto= Object. getPrototypeOf ( proto)
}
}
console. log ( myInstanceof ( {
x : 10 } , Object) )
3.手写new操作符
function myNew ( constructor, ... args ) {
let obj= {
}
obj= Object. create ( constructor. prototype)
let res= constructor . apply ( obj, args)
return ( typeof res== 'object' || typeof res== 'function' ) ? res: obj
}
function Cat ( name ) {
this . name= name
}
Cat . prototype. call = function ( ) {
console. log ( this . name+ 'call' )
}
var cat= myNew ( Cat, 'ljw' )
cat . call ( )
4.手写防抖函数
function debounce ( fn, delay ) {
let timer= null
let that= this
let flag= true
return function ( ... args) {
if ( flag) {
fn . apply ( that, args)
flag= false
}
clearTimeout ( timer)
timer= setTimeout ( ( ) => {
fn . apply ( that, args)
} , delay)
}
}
function fn ( i ) {
console. log ( i)
}
var f= debounce ( fn, 2000 )
f ( 1 )
f ( 2 )
setTimeout ( ( ) => {
f ( 3 ) } , 2001 )
f ( 4 )
5.手写节流函数
function throttle ( fn, delay ) {
let pre= new Date ( )
let that= this
let flag= true
return function ( ... args) {
if ( flag) {
fn . apply ( that, args)
flag= false
}
let now= new Date ( )
if ( now- pre>= delay) {
fn . apply ( that, args)
pre= now
}
}
}
function fn ( i ) {
console. log ( i)
}
var f= throttle ( fn, 2000 )
f ( 1 )
f ( 2 )
setTimeout ( ( ) => {
f ( 3 ) } , 2000 )
setTimeout ( ( ) => {
f ( 4 ) } , 5002 )
6.手写类型判断函数
function mytype ( target ) {
target= Object . prototype. toString . call ( target)
return target. slice ( 8 , - 1 )
}
console. log ( mytype ( 8 ) )
7.手写call 函数
Function . prototype. mycall = function ( context, ... args ) {
let res= null
context. fn= this
res= context. fn ( ... args)
delete context. fn
return res
}
function f ( a, b ) {
let x= a+ b
console. log ( this . x)
}
var obj= {
x : 10 }
f. mycall ( obj, 1 , 2 )
8.手写apply函数
Function . prototype. myapply = function ( context, args ) {
let res= null
context. fn= this
context. fn ( ... args)
delete context. fn
return res
}
function f ( a, b ) {
let x= a+ b
console. log ( this . x)
}
var obj= {
x : 10 }
f. myapply ( obj, [ 1 , 2 ] )
9.手写 bind函数
Function . prototype. mybind = function ( context, ... args ) {
let fn= this
return function F ( ... inArgs) {
if ( this instanceof F ) {
return fn . apply ( this , args. concat ( inArgs) )
} else {
return fn . apply ( context, args. concat ( inArgs) )
}
}
}
function f ( a, b ) {
this . c= a+ b
console. log ( this )
}
var obj= {
x : 10 }
var newObj= f. mybind ( obj, 1 )
new newObj ( 2 )
10.继承
寄生组合
function Animal ( name ) {
this . name= name
}
Animal . prototype. eat = function ( ) {
console. log ( this . name+ 'eat' )
}
function Cat ( name, age ) {
Animal . call ( this , name)
this . age= age
}
Cat . prototype= Object. create ( Animal . prototype)
Cat . prototype. constructor= Cat
var cat= new Cat ( 'ljw' , 19 )
cat. eat ( )
ES6 class
class Animal {
constructor ( name ) {
this . name= name
}
eat ( ) {
console. log ( this . name+ 'eat' )
}
}
class Cat extends Animal {
constructor ( name, age ) {
super ( name)
this . age= age
}
eat ( ) {
super . eat ( )
console. log ( 'hh' )
}
}
var cat= new Cat ( 'ljw' , 19 )
cat. eat ( )
11.实现浅拷贝
function shallowCopy ( target ) {
let res= Array. isArray ( target) ? [ ] : {
}
for ( let key in target) {
if ( target. hasOwnProperty ( key) ) {
res[ key] = target[ key]
}
}
return res
}
function shallowCopy ( target ) {
return {
... target}
}
function shallowCopy ( target ) {
return Object. assign ( {
} , target)
}
function shallowCopy ( target ) {
return [ ... target]
}
function shallowCopy ( target ) {
return target. slice ( )
}
function shallowCopy ( target ) {
return target. concat ( )
}
var target= [ 1 , 2 , [ 2 , 3 ] ]
var newTarget= shallowCopy ( target)
newTarget[ 1 ] = 1
newTarget[ 2 ] [ 0 ] = 1
console. log ( target)
console. log ( newTarget)
12.实现深拷贝
let map= new WeakMap ( )
function deepCopy ( target ) {
let res= {
}
let tmp= map. get ( target)
if ( tmp) {
return tmp
} else {
map. set ( target, res)
}
for ( let key in target) {
if ( target. hasOwnProperty ( key) ) {
res[ key] = typeof target[ key] == 'object' ? deepCopy ( target[ key] ) : target[ key]
}
}
return res
}
function deepCopy ( target ) {
return JSON . parse ( JSON . stringify ( target) )
}
var target= {
x : 10 ,
y : {
z : 2
}
}
var newTarget= deepCopy ( target)
newTarget. x= 1
newTarget. y. z= 1
console. log ( target)
console. log ( newTarget)
lodash
_. cloneDeep ( target)
13.实现数组元素求和
function sum ( arr ) {
return arr. reduce ( ( pre, cur ) => {
return pre+ cur} )
}
var arr= [ 1 , 2 , 3 , 4 , 5 ]
console. log ( sum ( arr) )
14.实现数组的扁平化
let arr= [ 1 , 2 , [ 3 , [ 4 , 5 ] ] ]
function flatten ( arr ) {
return arr. flat ( Infinity )
}
function flatten ( arr ) {
return arr. toString ( ) . split ( ',' ) . map ( item => Number ( item) )
}
function flatten ( arr ) {
let res= [ ]
arr. map ( item => {
if ( Array. isArray ( item) ) {
res= res. concat ( flatten ( item) )
}
res. push ( item)
} )
return res
}
function flatten ( arr ) {
while ( arr. some ( item => Array. isArray ( item) ) ) {
arr= [ ] . concat ( ... arr)
}
return arr
}
console. log ( flatten ( arr) )
15.实现数组去重
var arr= [ 1 , 2 , 3 , 4 , 2 , 3 , 4 , 5 ]
function demany ( arr ) {
return [ ... new Set ( arr) ]
}
function demany ( arr ) {
let map= {
}
let res= [ ]
arr. map ( item => {
if ( ! map[ item] ) {
map[ item] = true
res. push ( item)
}
} )
return res
}
console. log ( demany ( arr) )
16.promise实现方法
class MyPromise {
constructor ( fn ) {
this . state= 'pending'
this . res= undefined
this . err= undefined
this . onfullfilled= [ ]
this . onrejected= [ ]
let resolve = ( res ) => {
if ( this . state== 'pending' ) {
this . state= 'fullfilled'
this . res= res
this . onfullfilled. map ( item => {
item ( res)
} )
}
}
let reject = ( err ) => {
if ( this . state== 'pending' ) {
this . state= 'rejected'
this . err= err
this . onrejected. map ( item => {
item ( err)
} )
}
}
try {
fn ( resolve, reject)
} catch ( err) {
reject ( err)
}
}
then ( fn1, fn2 ) {
if ( this . state== 'pending' ) {
this . onfullfilled. push ( fn1)
this . onrejected. push ( fn2)
}
if ( this . state== 'fullfilled' ) {
fn1 ( this . res)
}
if ( this . state== 'rejected' ) {
fn2 ( this . err)
}
}
}
fn = function ( ) {
setTimeout ( ( ) => {
return 1
} )
}
p1= new MyPromise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
reject ( 1 )
} )
} )
p1. then ( ( res ) => {
console. log ( res)
} , ( err ) => {
console. error ( err)
} )
17.手写Promise.all
Promise. myall = function ( data ) {
return new Promise ( ( resolve, reject ) => {
if ( ! Array. isArray ( data) ) throw new Error ( 'type error' )
let result= [ ]
let len= data. length
let count= 0
for ( let i= 0 ; i< len; i++ ) {
Promise. resolve ( data[ i] ) . then ( ( res ) => {
result[ i] = res
count++
if ( count== len) {
return resolve ( result)
}
} , ( err ) => {
return reject ( err)
} )
}
} )
}
p1= new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
resolve ( 1 )
} , 2000 )
} )
p2= new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
reject ( 2 )
} )
} )
p3= new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
resolve ( 3 )
} , 1000 )
} )
Promise. myall ( [ p1, p3, 4 , p2] )
. then ( ( res ) => {
console. log ( res)
} , ( err ) => {
console. error ( err)
} )
18.手写Promise.race
Promise. myrace = function ( data ) {
return new Promise ( ( resolve, reject ) => {
if ( ! Array. isArray ( data) ) throw new Error ( 'type error' )
let len= data. length
for ( let i= 0 ; i< len; i++ ) {
Promise. resolve ( data[ i] ) . then ( ( res ) => {
resolve ( res)
} , ( err ) => {
reject ( err)
} )
}
} )
}
p1= new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
resolve ( 1 )
} , 2000 )
} )
p2= new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
reject ( 2 )
} )
} )
p3= new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
resolve ( 3 )
} , 1000 )
} )
Promise. myrace ( [ p1, p3] )
. then ( ( res ) => {
console. log ( res)
} , ( err ) => {
console. error ( err)
} )
p1= new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
resolve ( 1 )
} , 2000 )
} )
p1= new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
reject ( '请求超时' )
} , 1000 )
} )
Promise. race ( [ p1, p2] )
. then ( ( res ) => {
console. log ( res)
} , ( err ) => {
console. error ( err)
} )
19.Promise.resolve
Promise. myresolve = function ( res ) {
return new Promise ( ( resolve ) => {
resolve ( res)
} )
}
Promise. myresolve ( 1 ) . then ( ( res ) => {
console. log ( res)
} )
20.Promise的顺序执行方法
function a ( i ) {
return i+ 1
}
function b ( i ) {
return i* 2
}
function c ( i ) {
return i* 3
}
function fn ( str, cb ) {
cb ( str)
}
fn ( a ( 1 ) , ( str ) => {
fn ( b ( str) , ( str ) => {
console. log ( c ( str) )
} )
} )
function queue ( arr, init ) {
let p= Promise. resolve ( init)
arr. map ( item => {
p= p. then ( item)
} )
p. then ( ( res ) => {
console. log ( res)
} )
}
queue ( [ a, b, c] , 1 )
async function helper ( arr, init ) {
let res= await arr[ 0 ] ( init)
for ( let i= 1 ; i< arr. length; i++ ) {
res= await arr[ i] ( res)
}
console. log ( res)
}
helper ( [ a, b, c] , 1 )
21.Promise实现并发限制
function control ( stack, max, cb ) {
if ( stack. length==