手写call,apply和bind函数
手写call的实现
思路
let person = {
name: 'tom1',
say(){
console.log(this)
console.log(`my name is ${this.name}`)
}
}
let person2 = {
name: 'tom2'
}
Function.prototype.myCall = function (context) {
console.log(this) // 调用myCall的环境即为 person.say 函数
console.log(context) // person2
context.fn = this // 在person2 环境中加入一个新的函数fn,指向say
context.fn() // 在person环境中运行 fn函数(say函数)
}
person.say.myCall(person2)
具体实现
Function.prototype.myCall = function(context) {
if(typeof this !== 'function'){
throw new TypeError('Error')
}
}
// 如果没有传或传的值为空对象,context指向window
context = context || windows
context.fn = this
let arg = [...arguments].slice(1)
context.fn(...arg)
delete context.fn
手写apply的实现
Function.prototype.myApply = function(context) {
if(typeof this!== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
if(arguments[1]){
context.fn(...arguments[1])
}else{
context.fn()
}
}
person.say.myApply(person2)
手写bind的实现
Function.prototype.myBind = function(context){
if(typeof this !== 'function') {
throw new TypeError('Error')
}
let self =this
let arg = [...arguments].slice(1)
return function Newfn(){
// 因为柯里化形式传参,可实现f.bind(obj, 1)(2)
let newArg = [...arguments]
return sef.apply(context,arg.concat(newArg))
}
}