1.call实现
Function . prototype. $call = function ( context, ... args ) {
if ( typeof this !== "function" )
throw new TypeError ( "必须使用函数调用$call方法" )
context = context || globalThis
context = context instanceof Object ? context : new Object ( context)
let property = Symbol ( "property" )
Object. defineProperty ( context, property, {
enumerable : false ,
value : this
} )
let res = context[ property] ( ... args)
delete context[ property]
return res
}
Function . prototype. $call = function ( context, ... args ) {
return new Proxy ( this , {
apply ( target, thisArg, argArray ) {
return Reflect . apply ( target, context, args)
}
} ) ( ... args)
}
Function . prototype. $call = function ( context, ... args ) {
if ( typeof this !== "function" )
throw new TypeError ( "必须使用函数调用" )
context = context || globalThis
context = context instanceof Object ? context : Object ( context)
let func = this . toString ( ) . replace ( / this / g , "context" )
return eval ( ` ( ${ func} )( ${ args} ) ` )
}
2.apply实现
Function . prototype. $apply = function ( context, arg ) {
if ( typeof this !== "function" )
throw new TypeError ( "必须使用函数调用$apply方法" )
context = context || globalThis
context = context instanceof Object ? context : new Object ( context)
let property = Symbol ( "property" )
Object. defineProperty ( context, property, {
enumerable : false ,
value : this
} )
let res = context[ property] ( arg)
delete context[ property]
return res
}
Function . prototype. $apply = function ( context, arg ) {
return new Proxy ( this , {
apply ( target, thisArg, argArray ) {
return Reflect . apply ( target, context, arg)
}
} ) ( arg)
}
Function . prototype. $apply = function ( context, arg ) {
if ( typeof this !== "function" )
throw new TypeError ( "必须使用函数调用" )
context = context || globalThis
context = context instanceof Object ? context : Object ( context)
let func = this . toString ( ) . replace ( / this / g , "context" )
return eval ( ` ( ${ func} )( ${ arg} ) ` )
}
3.bind实现
Function . prototype. $bind = function ( context, ... args ) {
if ( typeof this !== "function" )
throw new TypeError ( "必须使用函数调用$bind方法" )
let that = this
return function Func ( ... arg) {
return that . call ( this instanceof Func ? this : context, ... [ ... args, ... arg] )
}
}
4.函数柯里化实现
function curry ( func, ... args ) {
if ( args. length === func. length)
return func ( ... args)
return function ( arg ) {
return curry ( func, ... [ ... args, arg] )
}
}
5.偏函数实现
function curry ( func, ... args ) {
if ( args. length === func. length)
return func ( ... args)
return function ( ... arg) {
return curry ( func, ... [ ... args, ... arg] )
}
}
6.记忆化函数实现
function memorize ( func ) {
let map = new Map ( )
return function ( ... args) {
let code = args. join ( "" )
if ( map. has ( code) )
return map. get ( code)
else {
map. set ( code, func ( ... args) )
return map. get ( code)
}
}
}
let f = memorize ( function ( n ) {
if ( n < 2 )
return n
return f ( n - 1 ) + f ( n - 2 )
} )
7.Promise A+实现
class VPromise {
static PENDING = "pending" ;
static FULFILLED = "fulfilled" ;
static REJECTED = "rejected" ;
static REJECT_ERROR = "can't reject yourself" ;
static RESOLVE_ERROR = "can't resolve yourself" ;
static STATUS_ERROR = "wrong status change" ;
#status = VPromise. PENDING ;
#value;
#reason;
#fulfilledCallbacks = [ ] ;
#rejectedCallbacks = [ ] ;
constructor ( func ) {
try {
typeof func === "function" &&
func . call ( this , this . #resolve . bind ( this ) , this . #reject . bind ( this ) ) ;
} catch ( err) {
this . #reject ( err) ;
}
}
#resolve ( value ) {
if ( this . #status !== VPromise. PENDING ) return ;
if ( value === this ) throw new TypeError ( VPromise. RESOLVE_ERROR ) ;
if ( value instanceof VPromise ) {
value. then (
( res ) => this . #resolve ( res) ,
( err ) => this . #reject ( err)
) ;
} else {
this . #value = value;
this . #status = VPromise. FULFILLED ;
( Array. isArray ( this . #fulfilledCallbacks)
? this . #fulfilledCallbacks
: [ ]
) . forEach ( ( func ) => {
typeof func === "function" && func ( this . #value) ;
} ) ;
}
}
#reject ( reason ) {
if ( this . #status !== VPromise. PENDING ) return ;
if ( reason === this ) throw new TypeError ( VPromise. REJECT_ERROR ) ;
if ( reason instanceof VPromise ) {
reason. then (
( res ) => this . #reject ( res) ,
( err ) => this . #reject ( err)
) ;
} else {
this . #reason = reason;
this . #status = VPromise. REJECTED ;
( Array. isArray ( this . #rejectedCallbacks)
? this . #rejectedCallbacks
: [ ]
) . forEach ( ( func ) => {
typeof func === "function" && func ( this . #reason) ;
} ) ;
}
}
then ( onFulfilledCallback, onRejectedCallback ) {
const forMatFulfilledCallback =
typeof onFulfilledCallback === "function"
? onFulfilledCallback
: ( value ) => value;
const forMatRejectedCallback =
typeof onRejectedCallback === "function"
? onRejectedCallback
: ( reason ) => reason;
return new VPromise ( ( resolve, reject ) => {
if ( this . #status === VPromise. PENDING ) {
const fulfilledCallbacks = Array. isArray ( this . #fulfilledCallbacks)
? this . #fulfilledCallbacks
: [ ] ;
fulfilledCallbacks. push ( ( value ) => {
try {
resolve ( forMatFulfilledCallback ( value) ) ;
} catch ( err) {
reject ( err) ;
}
} ) ;
this . #fulfilledCallbacks = fulfilledCallbacks;
const rejectedCallbacks = Array. isArray ( this . #rejectedCallbacks)
? this . #rejectedCallbacks
: [ ] ;
rejectedCallbacks. push ( ( reason ) => {
try {
reject ( forMatRejectedCallback ( reason) ) ;
} catch ( err) {
reject ( err) ;
}
} ) ;
this . #rejectedCallbacks = rejectedCallbacks;
} else if ( this . #status === VPromise. FULFILLED ) {
queueMicrotask ( ( ) => {
try {
resolve ( forMatFulfilledCallback ( this . #value) ) ;
} catch ( err) {
reject ( err) ;
}
} ) ;
} else if ( this . #status === VPromise. REJECTED ) {
queueMicrotask ( ( ) => {
try {
reject ( forMatRejectedCallback ( this . #reason) ) ;
} catch ( err) {
reject ( err) ;
}
} ) ;
} else {
throw new Error ( VPromise. STATUS_ERROR ) ;
}
} ) ;
}
catch ( onCatchCallback) {
return this . then (
null ,
( reason ) =>
typeof onCatchCallback === "function" && onCatchCallback ( reason)
) ;
}
finally ( onFianllyCallback) {
return this . then (
( value ) => {
typeof onFianllyCallback === "function" && onFianllyCallback ( value) ;
return value;
} ,
( reason ) => {
typeof onFianllyCallback === "function" && onFianllyCallback ( reason) ;
throw new Error ( reason) ;
}
) ;
}
static all ( promiseList ) {
return new VPromise ( ( resolve, reject ) => {
const result = [ ] ;
( Array. isArray ( promiseList) ? promiseList : [ ] ) . forEach (
( promise, index ) => {
if ( promise instanceof VPromise ) {
promise. then ( ( value ) => {
result[ index] = value;
result. length === promiseList. length && resolve ( result) ;
} , reject) ;
} else {
result[ index] = promise;
result. length === promiseList. length && resolve ( result) ;
}
}
) ;
} ) ;
}
static allSettled ( promiseList ) {
return new VPromise ( ( resolve ) => {
const result = [ ] ;
( Array. isArray ( promiseList) ? promiseList : [ ] ) . forEach (
( promise, index ) => {
if ( promise instanceof VPromise ) {
promise
. then (
( value ) => {
result[ index] = {
status : VPromise. FULFILLED ,
value,
} ;
} ,
( reason ) => {
result[ index] = {
status : VPromise. REJECTED ,
reason,
} ;
}
)
. then (
( ) => result. length === promiseList. length && resolve ( result)
) ;
} else {
result[ index] = {
status : VPromise. FULFILLED ,
value : promise,
} ;
result. length === promiseList. length && resolve ( result) ;
}
}
) ;
} ) ;
}
static race ( promiseList ) {
return new VPromise ( ( resolve, reject ) => {
( Array. isArray ( promiseList) ? promiseList : [ ] ) . forEach (
( promise ) =>
promise instanceof VPromise && promise. then ( resolve, reject)
) ;
} ) ;
}
static any ( promiseList ) {
return new VPromise ( ( resolve, reject ) => {
const result = [ ] ;
( Array. isArray ( promiseList) ? promiseList : [ ] ) . forEach (
( promise, index ) => {
if ( promise instanceof VPromise ) {
promise. then ( resolve, ( reason ) => {
result[ index] = reason;
result. length === promiseList. length && reject ( result) ;
} ) ;
}
}
) ;
} ) ;
}
static withResolvers ( ) {
let resolve;
let reject;
const promise = new VPromise ( ( res, rej ) => {
resolve = res;
reject = rej;
} ) ;
return { promise, resolve, reject } ;
}
}
8.Promise的all,allSettled,any,race,iterate实现
Promise. all = function ( ar ) {
if ( ar && typeof ar[ Symbol. iterator] !== "function" )
throw new TypeError ( "all方法的参数必须是可迭代对象" )
return new Promise ( ( resolve, reject ) => {
let cnt = 0
let ps = [ ]
ar = [ ... ar]
if ( ar. length === 0 )
resolve ( [ ] )
ar. forEach ( ( p, index ) => {
if ( p instanceof Promise ) {
p. then ( res => {
ps[ index] = res
if ( ++ cnt === ar. length)
resolve ( ps)
} , err => {
reject ( err)
} )
} else {
ps[ index] = p
if ( ++ cnt === ar. length)
resolve ( ps)
}
} )
} )
}
Promise. allSettled = function ( ar ) {
if ( ar && typeof ar[ Symbol. iterator] !== "function" )
throw new TypeError ( "allSettled参数必须是可迭代对象" )
return new Promise ( resolve => {
let cnt = 0
let ps = [ ]
ar = [ ... ar]
if ( ar. length === 0 )
resolve ( [ ] )
ar. forEach ( ( el, index ) => {
if ( el instanceof Promise ) {
el. then ( res => {
ps[ index] = { status : "fulfilled" , value : res }
if ( ++ cnt === ar. length)
resolve ( ps)
} , err => {
ps[ index] = { status : "rejected" , reason : err }
if ( ++ cnt === ar. length)
resolve ( ps)
} )
} else {
ps[ index] = { status : "fulfilled" , value : el }
if ( ++ cnt === ar. length)
resolve ( ps)
}
} )
} )
}
Promise. any = function ( ar ) {
if ( ar && typeof ar[ Symbol. iterator] !== "function" )
throw new TypeError ( "any方法的参数必须是可迭代对象" )
return new Promise ( ( resolve, reject ) => {
ar = [ ... ar]
if ( ar. length === 0 ) {
reject ( "All Promises are rejected" )
}
ar. forEach ( p => {
if ( p instanceof Promise )
p. then ( resolve)
else
resolve ( p)
} )
reject ( "All Promises are rejected" )
} )
}
Promsie. race = function ( ar ) {
if ( ar && typeof ar[ Symbol. iterator] !== "function" )
throw new TypeError ( "race方法的参数必须是可迭代对象" )
return new Promise ( ( resolve, reject ) => {
ar = [ ... ar]
ar. forEach ( el => {
if ( el instanceof Promise ) {
el. then ( resolve, reject)
} else
resolve ( el)
} )
} )
}
Promise. iterate = function ( ar ) {
if ( ar && typeof ar[ Symbol. iterator] !== "function" )
throw new TypeError ( "iterate方法的参数必须是可迭代对象" )
let promise = new Promise ( res => res ( ) )
ar = [ ... ar]
ar. forEach ( el => {
promise = promise. then ( ( ) => el)
} )
return promise
}
9.迭代器生成和遍历的实现
function fib ( n ) {
let a = 0 , b = 1 , cnt = 0
return {
[ Symbol. iterator] ( ) {
return this
} ,
next ( ) {
if ( ++ cnt === n + 1 )
return { done : true , value : undefined }
else {
[ a, b] = [ b, a + b]
return { done : false , value : a }
}
}
}
}
let f = fib ( 100 )
for ( let iter = f. next ( ) ; ! iter. done; iter = f. next ( ) )
if ( iter. value > 1000 )
break
else
console. log ( iter. value)
10.生成器生成和遍历的实现
function * fib ( n ) {
let a = 0 , b = 1
for ( let i = 0 ; i < n; i ++ ) {
[ a, b] = [ b, a + b]
yield a
}
}
let f = fib ( 100 )
for ( let iter = f. next ( ) ; ! iter. done; iter = f. next ( ) )
if ( iter. value > 1000 )
break
else
console. log ( iter. value)
11.异步迭代器生成和遍历的实现
function asyncIterator ( ar ) {
if ( ar && typeof ar[ Symbol. iterator] !== "function" )
throw new TypeError ( "参数必须是可迭代对象" )
let cnt = 0
return {
[ Symbol. asyncIterator] ( ) {
return this
} ,
next ( ) {
if ( cnt === ar. length)
return new Promise ( res => res ( { done : true , value : undefined } ) )
else if ( ar[ cnt] instanceof Promise )
return ar[ cnt ++ ] . then ( res => ( { done : false , value : res } ) , err => ( { done : false , value : err } ) )
else
return new Promise ( res => res ( { done : false , value : ar[ cnt ++ ] } ) )
}
}
}
let ar = [ new Promise ( res => {
setTimeout ( ( ) => {
res ( "p1" )
} , 3000 )
} ) , new Promise ( ( res, rej ) => {
setTimeout ( ( ) => {
rej ( "p2" )
} , 1000 )
} ) , 1 , 2 , 3 , "Danny" ] ;
( function asyncAuto ( asyncIterator ) {
let iter = asyncIterator. next ( ) ;
( function next ( ) {
iter. then ( res => {
if ( ! res. done) {
console. log ( res)
iter = asyncIterator. next ( )
next ( )
}
} )
} ) ( ) ;
} ) ( asyncIterator ( ar) )
12.async和await的实现
function * generator ( ) {
yield new Promise ( res => res ( "p1" ) )
yield 1
yield new Promise ( ( res, rej ) => rej ( "p2" ) )
yield "Danny"
}
( function generatorAuto ( generator ) {
let iter = generator. next ( ) ;
( function next ( ) {
if ( iter. value instanceof Promise )
iter. value. then ( res => {
console. log ( res)
iter = generator. next ( )
next ( )
} , err => {
console. log ( err)
iter = generator. next ( )
next ( )
} )
else if ( ! iter. done) {
console. log ( iter. value)
iter = generator. next ( )
next ( )
}
} ) ( )
} ) ( generator ( ) )