call、apply、bind的区别和自定义
来源: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: thisobj.tempFn = this// 调用obj的tempFn方法, 传入rags参数, 得到返回值const result = obj.tempFn(...args)// 删除obj上的temFndelete obj.tempFn// 返回方法的返回值return result}
Function.prototype.apply = function (obj, args) {// 处理obj是undefined或者null的情况if (obj===undefined || obj===null) {obj = window}// 给obj添加一个方法: tempFn: thisobj.tempFn = this// 调用obj的tempFn方法, 传入rags参数, 得到返回值const result = obj.tempFn(...args)// 删除obj上的temFndelete 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 2fn.apply(obj, [1, 2]) // 相当于obj.fn(1, 2) 打印: 1 2 obj 2fn.call(null, 1, 2) // 和直接调用一样 打印: 1 2 Window 2fn.bind(obj)(3, 4) // 打印: 3, 4 obj 2fn.bind(obj,10)(3, 4) // 打印: 10, 3 obj 3

评论
