手写call、apply、bind方法
call、apply、bind 都是为了改变函数运行时上下文(this指向)而存在的。
它们有什么不同?
- 它们接收的第一个参数都是函数上下文也就是要绑定的this指向。
- apply的第二个参数是一个参数数组,call和bind的第二个及之后的参数作为函数实参按顺序传入。
- bind绑定完this的指向后会返回一个新的函数体,不会被立即调用,其他两个会立即调用。
实现call方法
Function.prototype.myCall = function(thisObj,...args){
if(typeof this !== 'function') { // this 必须是函数
throw new TypeError(`It's must be a function`)
}
thisObj = thisObj || window
let fn = Symbol()
thisObj[fn] = this
let res = thisObj[fn](...args)
delete thisObj[fn]
return res
}
实现apply方法
Function.prototype.myApply = function(thisObj,args=[]){
if(typeof this !== 'function') { // this 必须是函数
throw new TypeError(`It's must be a function`)
}
thisObj = thisObj || window
let fn = Symbol()
thisObj[fn] = this
let res = thisObj[fn](...args)
delete thisObj[fn]
return res
}
实现bind方法
Function.prototype.myBind = function (thisObj, ...args) {
const fn = this
if(typeof fn !== 'function'){
throw new TypeError('It must be a function')
}
thisObj = thisObj || window
return function (...otherArgs) {
return fn.apply(thisObj, [...args, ...otherArgs])
}
}
如果要支持new:
Function.prototype.myBind = function (thisObj, ...args) {
var fn= this
if(typeof fn !== 'function'){
throw new TypeError('It must be a function')
}
thisObj = thisObj || window
// new优先级
var result = function () {
return fn.apply(this instanceof result ? this : thisObj, args.concat(Array.prototype.slice.call(arguments)))
}
// 继承原型上的属性和方法
result.prototype = Object.create(fn.prototype)
return result
}

浙公网安备 33010602011771号