手撕call、apply和bind
call
Function.prototype.myCall = function (context, ...params) {
context == null ? context = window : null
if (!/^(function|object)$/.test(typeof context)) context = Object(context)
let key = Symbol('key'),
result
context[key] = this
result = context[key](...params)
delete context[key]
return result
}
apply
Function.prototype.myApply = function (context, params) {
context == null ? context = window : null
if (!/^(function|object)$/.test(typeof context)) context = Object(context)
let key = Symbol('key'),
result
context[key] = this
result = context[key](...params)
delete context[key]
return result
}
bind
Function.prototype.myBind = function (context, ...params) {
context == null ? context = window : null
if (!/^(function|object)$/.test(typeof context)) context = Object(context)
let self = this
return function (...argu) {
params = params.concat(argu)
let key = Symbol('key'),
result
context[key] = self
result = context[key](...params)
delete context[key]
return result
}
}
function fn(x, y) {
this.total = x + y
return this
}
let obj = {
name: 'tw'
}
console.log(fn.myCall(obj, 10, 20))
function func() {
console.log(this, arguments)
}
document.body.onclick = func.myBind(10, 100, 200)