Function.prototype.apply
call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。
TypeScript定义
/**
* Calls the function with the specified object as the this value and the elements of specified array as the arguments.
* @param thisArg The object to be used as the this object.
* @param args An array of argument values to be passed to the function.
*/
apply<T, R>(this: (this: T) => R, thisArg: T): R;
apply<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R;
手写实现
interface Function {
myApply: Function
}
Function.prototype.myApply = function(context: any, args?: any[]) {
if (typeof context !== 'object') {
throw Error()
}
const symbol = Symbol()
context[symbol] = this
const res = args ? context[symbol](...args) : context[symbol]()
delete context[symbol]
return res
}
Function.prototype.call
TypeScript定义
/**
* Calls the function with the specified object as the this value and the specified rest arguments as the arguments.
* @param thisArg The object to be used as the this object.
* @param args Argument values to be passed to the function.
*/
call<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A): R;
手写实现
interface Function {
myCall: Function
}
Function.prototype.myCall = function (context: any, ...args: any[]) {
if (typeof context !== 'object') {
throw Error()
}
const symbol = Symbol()
context[symbol] = this
const res = context[symbol](...args)
delete context[symbol]
return res
}
Function.prototype.bind
TypeScript定义
/**
* For a given function, creates a bound function that has the same body as the original function.
* The this object of the bound function is associated with the specified object, and has the specified initial parameters.
* @param thisArg The object to be used as the this object.
* @param args Arguments to bind to the parameters of the function.
*/
bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;
bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R;
bind<T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R;
bind<T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R;
bind<T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R;
bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R;
手写实现
interface Function {
myBind: Function
}
Function.prototype.myBind = function (context: any, args1?: any[]) {
if (typeof context !== 'object') {
throw Error()
}
return (...args2: any[]) => {
if (!args1) {
return this.myApply(context, args2)
}
return this.myApply(context, args1.concat(args2))
}
}