js中call,apply和bind函数原理解析
js中call,apply和bind广泛应用,都可以用来改变this指向,call和apply的区别在于参数传递的不同,前者是参数序列,后者是数组。bind的函数也是参数序列,但是需要生成一个新的函数
1.call,传递的参数为序列
Function.prototype.mycall = function(fn) {
if(typeof(this) !='function'){ // 容错处理
throw new TypeError('not function')
}
fn = fn || window // 如果传的是null 则默认window
fn.caller= this ; // this指向调用者
let arg = [...argument].slice(1) // 使用扩展运算符把伪数组转化为真数组
let result = arg.length > 0 ? fn.caller(...arg) : fn.caller()
delete fn.caller
return result
}
2.apply函数,参数数数组
Function.prototype.myapply= function(fn) {
if(typeof(this) !='function'){ // 容错处理
throw new TypeError('not function')
}
fn = fn || window // 如果传的是null 则默认window
fn.caller= this ; // this指向调用者
let arg =argument[1] // 获取参数数组
let result = arg ? fn.caller(...arg) : fn.caller()
delete fn.caller
return result
}
3.call函数,需要用到柯里化和闭包
Function.prototype.mybind= function(fn) {
// fn 调用该方法的第一个值
if(type this != 'function') {
throw new TypeError('not function')
}
let _this = this; //this指向.myBind 前面的方法,为fn函数添加一个方法,与this相同指向
let arg = [...arguments].slice(1)
return function F() {
// 处理函数使用new的情况
if (this instanceof F) {
return new _this(...arg, ...arguments)
} else {
return _this.apply(fn, arg.concat(...arguments))
}
}