分别介绍使用es5实现和es6实现。废话不多说,直接上代码
es5实现:
// 在函数构造器Function的原型上增加customCall方法,使每个函数都能调用customCall方法
Function.prototype.customCall = function () {
// 函数参数
var args = []
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i])
}
// 获取上下文和参数
var ctx = args[0], params = args.slice(1)
// this表示被调用函数,把它传递给下上文的自定义属性
ctx.customFn = this
// 拼凑参数并使用eval执行函数
var res = eval('ctx.customFn(' + params.join(',') + ')')
// 删除上下文自定义属性
delete ctx.customFn
// 返回函数调用结果
return res
}
es6实现:
Function.prototype.customCall = function (ctx, ...params) {
ctx.customFn = this
const res = ctx.customFn(...params)
delete ctx.customFn
return res
}
调用方式:
var person1 = {
name: '张三',
say: function (age) {
console.log('大家好!我叫' + this.name + ',今年' + age + '岁')
}
}
var person2 = {
name: '李四'
}
person1.say(21) // 大家好!我叫张三,今年21岁
person1.say.customCall(person2, 18) // 大家好!我叫李四,今年18岁