注:只是简单练习实现这几种方法,this指向,调用关系等,并不会考虑一些边界情况
1.手写实现call方法
// call函数的实现
function foo() {
console.log('foo函数被执行', this)
}
//自定义call函数
Function.prototype.myCall = function (thisArg, ...resParams) {
//获取需要被执行的函数
var fn = this
//对thisArg转成对象类型(防止它传入的是非对象类型),并且防止传入null和undefined时this指向不正确的问题
thisArg = thisArg !== null || thisArg !== undefined ? Object(thisArg) : window
thisArg.fn = fn
// 将计算的结果返回
var result = thisArg.fn(...resParams)
delete thisArg.fn // 调用完可以删除fn属性
return result
}
foo.myCall({name: 'foo'}, 1, 2, 3)
2.手写实现apply方法
// 实现apply方法
Function.prototype.myApply = function (thisArg, argArray = []) {
//1.获取到要执行的参数
var fn = this
//2.对thisArg转成对象类型(防止它传入的是非对象类型),并且防止传入null和undefined时this指向不正确的问题
thisArg = thisArg !== null || thisArg !== undefined ? Object(thisArg) : window
// 执行函数
thisArg.fn = fn
var result = thisArg.fn(...argArray)
delete thisArg.fn
return result
}
function foo() {
console.log('foo函数被执行', this)
}
foo.myApply({name: 'foo'}, ['haha'])
3.手写实现bind方法
Function.prototype.myBind = function (thisArg, ...argArray) {
// 获取需要调用的函数
var fn = this
// 绑定this,判断传入的要绑定的对象是否为null,undefined,如果是将this指向为window
thisArg = thisArg !== null || thisArg !== undefined ? Object(thisArg) : window
function proxyFn(...args) {
thisArg.fn = fn
var finalArg = [...argArray, ...args]
var result = thisArg.fn(...finalArg)
delete thisArg.fn
return result
}
return proxyFn
}
function foo(...args) {
console.log(this, ...args)
}
var res = foo.myBind(0, 10)
res(20)
总结
以上就是简单的手写实现apply,call,bind方法,只是简单的满足功能,并未着重考虑一些边界问题