一、函数相关
call()& apply()& bind()
API说明
- call()
- 语法: call(fn, obj, ...args)
- 功能: 执行fn, 使this为obj, 并将后面的n个参数传给fn(功能等同于函数对象的call方法)
- apply()
- 语法: apply(fn, obj, args)
- 功能: 执行fn, 使this为obj, 并将args数组中的元素传给fn(功能等同于函数对象的apply方法)
- bind()
- 语法: bind(fn, obj, ...args)
- 功能: 给fn绑定this为obj, 并指定参数为后面的n个参数 (功能等同于函数对象的bind方法)
实现说明
- 区别call()/apply()/bind()
- call(obj)/apply(obj): 调用函数, 指定函数中的this为第一个参数的值
- bind(obj): 返回一个新的函数, 新函数内部会调用原来的函数, 且this为bind()指定的第一参数的值
- 注意: 如果obj是null/undefined, this为window
- 应用
- call()/apply()应用: 根据伪数组生成真数组
- bind(): react中组件的自定义方法 / vue中的事件回调函数内部
- 自定义call()/apply()
- 给obj添加一个临时方法, 方法名任意, 值为当前函数
- 通过obj调用这个临时方法, 并将接收的参数传入
- 删除obj上的这个临时方法属性
- 自定义实现bind()
- 返回一个新函数
- 在新函数内部通过原函数对象的call方法来执行原函数
- 指定原函数的this为obj
- 指定参数为bind调用的参数和后面新函数调用的参数
1、自定义函数对象的call方法
call.js
/*
自定义函数对象的call方法
Fn:要执行的函数
obj:函数运行时this指向的对象
args:函数运行时的参数
*/
function call(Fn, obj, ...args) {// 如果obj是undefined/null, this指定为windowif (obj === undefined || obj === null) {// return fn(...args)obj = window}// 给obj添加一个临时方法, 方法指向的函数就是fnobj.tempFn = Fn;//tempFn内部在执行时this是指向obj的,变相实现了this指向obj这样一个效果// 通过obj来调用这个方法 ==> 也就会执行fn函数 ==> 此时fn中的this肯定为objconst result = obj.tempFn(...args);// 删除obj上的临时方法delete obj.tempFn;// 返回fn执行的结果return result;
}
<!DOCTYPE html>
<html lang="en"><head><title></title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link href="css/style.css" rel="stylesheet"><script src="./call.js"></script>
</head><body><script>// 声明一个函数function add(a, b) {return a + b + this.c;}// 声明一个对象let obj = {c: 521}//添加全局属性window.c = 1314;// 执行call函数console.log(call(add, obj, 10, 20));// 151console.log(call(add, null, 30, 40));// 1384</script>
</body></html>
2、自定义函数对象的apply方法
/*
自定义函数对象的Apply方法
Fn:要执行的函数
obj:函数运行时this指向的对象
args:函数运行时的参数
*/
// 改变this的指向,执行函数,返回结果
function apply(Fn, obj, ...args) {if (obj === undefined || obj === null) {obj = window;}//给obj添加一个临时的方法,方法指向的函数就是Fnobj.tempFn = Fn;// 通过obj来调用这个方法 ==> 也就会执行fn函数 ==> 此时fn中的this肯定为objconst result = obj.tempFn(...args)// 删除obj上的临时方法delete obj.tempFn// 返回fn执行的结果return resultv
}
<!DOCTYPE html>
<html lang="en"><head><title></title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link href="css/style.css" rel="stylesheet"><script src="./call.js"></script>
</head><body><script>// 声明一个函数function add(a, b) {return a + b + this.c;}// 声明一个对象let obj = {c: 521}//添加全局属性window.c = 1314;// 执行call函数console.log(apply(add, obj, 10, 20));// 151console.log(apply(add, null, 30, 40));// 1384</script>
</body></html>
3、自定义函数对象的bind方法
import {call} from './call'
/* 自定义函数对象的bind方法
*/
export function bind(fn, obj, ...args) {console.log('bind()')// 返回一个新函数return (... args2) => {// 通过call调用原函数, 并指定this为obj, 实参为args与args2return call(fn, obj, ...args, ...args2)}
}