call
const person = {
name: 'zaaa',
test: function(age, sex) {
console.log(this.name + '已经' + age + ',' + '是个' + sex ')
}
}
var son = {
}
Function.prototype.newCall = function() {
if (typeof this !== 'function') return new Error('The ' + this + ' should be a function')
// 得到当前的方法
let funcThis = this
// 其余参数
let arr = [...arguments]
// 要改变到的对象 --- 如果没有传参,就指向window
let to = arr.shift() || window
arr = arr[0]
// 得到的方法加在要改变到的对象身上
to.fn = funcThis
// 执行
let result = to.fn(...arr)
delete to.fn
return result
}
//person.test.newCall(son, 12, 'man')
输出结果:undefined已经12,是个man
此时this已经改变了,this.name当然是undefinded了!
apply
apply 实现方法类似,只要把第二个参数改成数组就行
Function.prototype.newApply = function() {
if (typeof this !== 'function') return new Error('The ' + this + ' should be a function')
// 得到当前的方法
let funcThis = this
let arr = [...arguments]
// 要改变到的对象 --- 如果没有传参,就指向window
let to = arr.shift() || window
// 得到的方法加在要改变到的对象身上
arr = arr[0]
to.fn = funcThis
// 执行
let result = arr ? to.fn(...arr) : to.fn()
delete to.fn
return result
}
// person.test.newApply(son, [12, 'man'])
bind
bind 方法与 call 类似, 只是它变成了一个回调函数
Function.prototype.newBind = function() {
if (typeof this !== 'function') return new Error('The ' + this + ' should be a function')
// 得到当前的方法
let funcThis = this
// 其余参数
let arr = [...arguments]
// 第一个参数
let to = arr.shift() || window
// 第二个参数
arr = arr[0]
return function() {
funcThis.newCall(to, arr)
}
}
let a = person.test.newBind(son, [12, 'man'])
a()