一、函数相关
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指定为window
if (obj === undefined || obj === null) {
// return fn(...args)
obj = window
}
// 给obj添加一个临时方法, 方法指向的函数就是fn
obj.tempFn = Fn;//tempFn内部在执行时this是指向obj的,变相实现了this指向obj这样一个效果
// 通过obj来调用这个方法 ==> 也就会执行fn函数 ==> 此时fn中的this肯定为obj
const 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));// 151
console.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添加一个临时的方法,方法指向的函数就是Fn
obj.tempFn = Fn;
// 通过obj来调用这个方法 ==> 也就会执行fn函数 ==> 此时fn中的this肯定为obj
const 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));// 151
console.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与args2
return call(fn, obj, ...args, ...args2)
}
}