call、apply、bind的区别和自定义
SegmentFault
共 2295字,需浏览 5分钟
·
2020-09-04 13:19
来源:SegmentFault 思否社区
作者:黄万通
区别call()/apply()/bind()
call(obj)/apply(obj): 调用函数, 指定函数中的this为第一个参数的值 bind(obj): 返回一个新的函数, 新函数内部会调用原来的函数, 且this为bind()指定的第一参数的值 注意: 如果obj是null/undefined, this为window
应用
call()/bind()应用: 根据伪数组生成真数组
bind(): react中组件的自定义方法 / vue中的事件回调函数内部自定义call()/apply()
1). 给obj添加一个临时方法, 方法名任意, 值为当前函数
2). 通过obj调用这个临时方法, 并将接收的参数传入
3). 删除obj上的这个临时方法属性自定义实现bind()
1). 返回一个新函数
2). 在新函数内部通过原函数对象的call方法来执行原函数, 指定原函数的this为obj指定参数为bind调用的参数和后面新函数调用的参数
自定义call()/apply()/bind()
自定义call()/apply()
1). 给obj添加一个临时方法, 方法名任意, 值为当前函数
2). 通过obj调用这个临时方法, 并将接收的参数传入
3). 删除obj上的这个临时方法属性
4). 代码
Function.prototype.call = function (obj, ...args) {
// this() 就是调用当前函数实例
// 处理obj是undefined或者null的情况
if (obj===undefined || obj===null) {
obj = window
}
// 给obj添加一个方法: tempFn: this
obj.tempFn = this
// 调用obj的tempFn方法, 传入rags参数, 得到返回值
const result = obj.tempFn(...args)
// 删除obj上的temFn
delete obj.tempFn
// 返回方法的返回值
return result
}
Function.prototype.apply = function (obj, args) {
// 处理obj是undefined或者null的情况
if (obj===undefined || obj===null) {
obj = window
}
// 给obj添加一个方法: tempFn: this
obj.tempFn = this
// 调用obj的tempFn方法, 传入rags参数, 得到返回值
const result = obj.tempFn(...args)
// 删除obj上的temFn
delete obj.tempFn
// 返回方法的返回值
return result
}
自定义实现bind()
1). 返回一个新函数
2). 在新函数内部通过原函数对象的call方法来执行原函数指定this为obj指定参数为bind调用的参数和后面新函数调用的参数
3).代码
Function.prototype.bind = function (obj, ...args) {
// 返回一个新函数
return (...args2) => {
// 调用原来函数, 指定this为obj, 参数列表由args和args2依次组成
return this.call(obj, ...args, ...args2)
}
}
测试
function fn(x, y) {
this.aaa = 3 // 会给改变this对象添加aaa属性的值为3,如果指定的对象为null会给window添加
console.log(x, y, this, arguments.length)
return x + y
}
const obj = {m: 0}
fn(10, 20) // 直接调用会在window全局对象下添加aaa属性
fn.call(obj, 10, 20) // 相当于obj.fn(10, 20) 打印: 10 20 obj 2
fn.apply(obj, [1, 2]) // 相当于obj.fn(1, 2) 打印: 1 2 obj 2
fn.call(null, 1, 2) // 和直接调用一样 打印: 1 2 Window 2
fn.bind(obj)(3, 4) // 打印: 3, 4 obj 2
fn.bind(obj,10)(3, 4) // 打印: 10, 3 obj 3
评论