# call
Function.prototype._call = function(obj){
// 首先要获取调用call的函数,用this可以获取
var obj = obj || window
obj.fn = this
var args = [...arguments].slice(1)
var result = obj.fn(...args)
delete obj.fn
return result
}
# apply
Function.prototype._apply = function(obj){
var obj = obj || window
obj.fn = this
var result
// 检查是否有入参,arguments[0] 指向的是this,arguments[1]指向的是入参数组
if(arguments[1]){
result = obj.fn(...arguments[1])
}else{
result = obj.fn()
}
delete obj.fn
return result
}
# bind
Function.prototype._bind = function(obj){
if(typeof this != "function"){
throw Error("not a function")
}
var fn = this
var args = [...arguments].slice(1)
var resFn = function(){
return fn.apply(this instanceof resFn ? this : obj, args.concat(...arguments))
}
function tmp(){}
tmp.prototype = this.prototype
resFn.prototype = new tmp()
return resFn
}
Function.prototype._bind2 = function(context) {
//返回一个绑定this的函数,我们需要在此保存this
let self = this
// 可以支持柯里化传参,保存参数
let arg = [...arguments].slice(1)
// 返回一个函数
return function() {
//同样因为支持柯里化形式传参我们需要再次获取存储参数
let newArg = [...arguments]
console.log(newArg)
// 返回函数绑定this,传入两次保存的参数
//考虑返回函数有返回值做了return
return self.apply(context, arg.concat(newArg))
}
}
let foo = {
value: 1
}
function bar(name, age){
console.log(name)
console.log(age)
console.log(this.value)
}
bar._call(foo, "xiaoming", "18")
bar._apply(foo, ["xiaohuang", "28"])
bar._bind(foo, "xiaopeng", "38")()