1. apply-call-bind
1.1 基础版本
function foo(name, age) {
console.log(this, name, age)
}
Function.prototype.hyapply = function (thisArg) {
thisArg = thisArg === null || thisArg === undefined ? window : Object(thisArg)
Object.defineProperty(thisArg, 'fn', {
enumerable: false,
configurable: true,
value: this
})
thisArg.fn()
delete thisArg.fn
}
foo.hyapply({ name: 'why' }, ['james', 25])
foo.hyapply(123, ['why', 18])
foo.hyapply(null, ['kobe', 30])
Function.prototype.hycall = function (...thisArg) {
thisArg = thisArg === null || thisArg === undefined ? window : Object(thisArg)
Object.defineProperty(thisArg, 'fn', {
enumerable: false,
configurable: true,
value: this
})
thisArg.fn()
delete thisArg.fn
}
foo.hyapply({ name: 'why' }, 'james', 25)
foo.hyapply(123, 'why', 18)
foo.hyapply(null, 'kobe', 30)
1.2 函数封装
function foo(name, age) {
console.log(this, name, age)
}
function execFn(thisArg, otherArgs, fn) {
thisArg = thisArg === null || thisArg === undefined ? window : Object(thisArg)
Object.defineProperty(thisArg, 'fn', {
enumerable: false,
configurable: true,
value: fn
})
thisArg.fn(...otherArgs)
delete thisArg.fn
}
Function.prototype.hyapply = function (thisArg, otherArgs) {
execFn(thisArg, otherArgs, this)
}
foo.hyapply({ name: 'why' }, ['james', 25])
foo.hyapply(123, ['why', 18])
foo.hyapply(null, ['kobe', 30])
Function.prototype.hycall = function (thisArg, ...otherArgs) {
execFn(thisArg, otherArgs, this)
}
foo.hycall({ name: 'why' }, 'james', 25)
foo.hycall(123, 'why', 18)
foo.hycall(null, 'kobe', 30)
1.3 封装到原型链上
function foo(name, age) {
console.log(this, name, age)
}
Function.prototype.hyexec = function (thisArg, otherArgs) {
thisArg = thisArg === null || thisArg === undefined ? window : Object(thisArg)
Object.defineProperty(thisArg, 'fn', {
enumerable: false,
configurable: true,
value: this
})
thisArg.fn(...otherArgs)
delete thisArg.fn
}
Function.prototype.hyapply = function (thisArg, otherArgs) {
this.hyexec(thisArg, otherArgs)
}
foo.hyapply({ name: 'why' }, ['james', 25])
foo.hyapply(123, ['why', 18])
foo.hyapply(null, ['kobe', 30])
Function.prototype.hycall = function (thisArg, ...otherArgs) {
this.hyexec(thisArg, otherArgs)
}
foo.hycall({ name: 'why' }, 'james', 25)
foo.hycall(123, 'why', 18)
foo.hycall(null, 'kobe', 30)
1.4 bind
function foo(name, age, height, address) {
console.log(this, name, age, height, address)
}
Function.prototype.hybind = function (thisArg, ...otherArgs) {
thisArg = thisArg === null || thisArg === undefined ? window : thisArg
Object.defineProperty(thisArg, 'fn', {
configurable: true,
enumerable: false,
writable: false,
value: this
})
return (...newArgs) => {
var allArgs = [...otherArgs, ...newArgs]
thisArg.fn(...allArgs)
}
}
var newFn = foo.hybind({ name: 'lwz' }, 'why', 18)
newFn(1.88, '北京市')