JS手写题
1. 手写 apply
方法
Function . prototype. myApply = function ( thisArg, argsArray ) {
thisArg = thisArg || globalThis;
const fn = Symbol ( 'fn' ) ;
thisArg[ fn] = this ;
argsArray = argsArray || [ ] ;
const result = thisArg[ fn] ( ... argsArray) ;
delete thisArg[ fn] ;
return result;
} ;
const food = {
name: '西兰花炒蛋' ,
} ;
function func2 ( numA, numB, numC ) {
console. log ( this ) ;
console. log ( numA, numB, numC) ;
return numA + numB + numC;
}
const res2 = func2. myApply ( food, [ 2 , 4 , 6 ] ) ;
console. log ( 'res2:' , res2) ;
2. 手写 call
方法
Function . prototype. myCall = function ( thisArg, ... args ) {
thisArg = thisArg || globalThis;
const fn = Symbol ( 'fn' ) ;
thisArg[ fn] = this ;
const result = thisArg[ fn] ( ... args) ;
delete thisArg[ fn] ;
return result;
} ;
const food = {
name: '西兰花炒蛋' ,
} ;
function func2 ( numA, numB, numC ) {
console. log ( this ) ;
console. log ( numA, numB, numC) ;
return numA + numB + numC;
}
const res2 = func2. myCall ( food, 2 , 4 , 6 ) ;
console. log ( 'res' , res2) ;
3. 手写 bind
方法
Function . prototype. myBind = function ( thisArg, ... args ) {
const self = this ;
return function boundFunction ( ... newArgs) {
const isNewOperatorUsed = this instanceof boundFunction ;
const context = isNewOperatorUsed ? this : thisArg;
return self . apply ( context, [ ... args, ... newArgs] ) ;
} ;
} ;
const person = {
name: 'Tom' ,
} ;
function greet ( greeting, punctuation ) {
console. log ( ` ${ greeting} , ${ this . name} ${ punctuation} ` ) ;
}
const boundGreet = greet. myBind ( person, 'Hello' ) ;
boundGreet ( '!' ) ;
4. 手写 AJAX 请求
function ajax ( url, method, data = null ) {
const xhr = new XMLHttpRequest ( ) ;
xhr. open ( method, url, true ) ;
xhr. onreadystatechange = function ( ) {
if ( xhr. readyState === 4 ) {
if ( ( xhr. status >= 200 && xhr. status < 300 ) || xhr. status === 304 ) {
alert ( xhr. responseText) ;
} else {
console. log ( "Request was unsuccessful: " + xhr. status) ;
}
}
} ;
if ( method. toLowerCase ( ) === 'post' ) {
xhr. setRequestHeader ( "Content-Type" , "application/x-www-form-urlencoded" ) ;
}
xhr. send ( data) ;
}
ajax ( 'https://jsonplaceholder.typicode.com/posts/1' , 'GET' ) ;
5. 防抖(Debounce)
function debounce ( func, wait ) {
let timeoutId;
return function ( ... args) {
if ( timeoutId) {
clearTimeout ( timeoutId) ;
}
timeoutId = setTimeout ( ( ) => {
func ( ... args) ;
} , wait) ;
} ;
}
6. 节流(Throttle)
function throttle ( func, wait = 0 ) {
let timeId;
return function ( ... args) {
if ( timeId !== undefined ) {
return ;
}
const _this = this ;
timeId = setTimeout ( ( ) => {
func . apply ( _this, args) ;
timeId = undefined ;
} , wait) ;
} ;
}
7. 数组扁平化
const arr = [ 1 , [ 2 , [ 3 , [ 4 ] ] , 5 ] ] ;
function flatten ( arr ) {
let result = [ ] ;
arr. forEach ( item => {
if ( Array. isArray ( item) ) {
result = result. concat ( flatten ( item) ) ;
} else {
result. push ( item) ;
}
} ) ;
return result;
}
console. log ( flatten ( arr) ) ;
8. 数组去重
let arr = [ 1 , 2 , 3 , 2 , 4 , 5 , 3 , 6 , 2 ] ;
function arrayToHeavy ( arr ) {
let newArr = [ ] ;
for ( let i = 0 ; i < arr. length; i++ ) {
if ( newArr. indexOf ( arr[ i] ) === - 1 ) {
newArr. push ( arr[ i] ) ;
}
}
return newArr;
}
console. log ( arrayToHeavy ( arr) ) ;
9. 柯里化
function sumMaker ( length ) {
let nums = [ ] ;
function sum ( ... args) {
nums. push ( ... args) ;
if ( nums. length >= length) {
const res = nums. slice ( 0 , length) . reduce ( ( p, v ) => p + v, 0 ) ;
nums = [ ] ;
return res;
} else {
return sum;
}
}
return sum;
}
const sum6 = sumMaker ( 6 ) ;
console. log ( sum6 ( 1 , 2 , 3 ) ( 4 , 5 , 6 ) ) ;
10. 浅拷贝
const original = {
name: 'John' ,
age: 30 ,
skills: [ 'javascript' , 'vue' ] ,
} ;
const copy = Object. assign ( { } , original) ;
copy. name = 'Alice' ;
copy. skills. push ( 'React' ) ;
console. log ( original) ;
console. log ( copy) ;
11. 深拷贝
function deepClone ( obj ) {
if ( typeof obj !== 'object' || obj === null ) {
return obj;
}
const result = Array. isArray ( obj) ? [ ] : { } ;
for ( const key in obj) {
if ( obj. hasOwnProperty ( key) ) {
result[ key] = deepClone ( obj[ key] ) ;
}
}
return result;
}
const obj1 = {
name: 'Alice' ,
age: 25 ,
skills: [ 'JavaScript' , 'Vue' , 'React' ] ,
details: {
hobbies: [ 'reading' , 'coding' ] ,
location: {
city: 'New York' ,
country: 'USA' ,
} ,
} ,
} ;
const obj2 = deepClone ( obj1) ;
obj2. name = 'Bob' ;
obj2. details. location. city = 'San Francisco' ;
console. log ( 'Original:' , obj1) ;
console. log ( 'Cloned:' , obj2) ;
12. 手写 new
function myNew ( constructor, ... args ) {
const obj = Object. create ( constructor. prototype) ;
const result = constructor . apply ( obj, args) ;
return typeof result === 'object' && result !== null ? result : obj;
}
function Person ( name, age ) {
this . name = name;
this . age = age;
}
Person . prototype. sayHello = function ( ) {
console. log ( ` Hello, my name is ${ this . name} , I am ${ this . age} years old. ` ) ;
} ;
const person1 = myNew ( Person, 'John' , 30 ) ;
person1. sayHello ( ) ;
13.实现sleep
function sleep ( func, delay ) {
return new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
resolve ( func ( ) )
} , delay)
} )
}
function say ( name ) {
console. log ( name)
}
async function go ( ) {
await sleep ( ( ) => say ( '张继科' ) , 1000 )
await sleep ( ( ) => say ( '马龙' ) , 2000 )
}
go ( )