一:手写call方法
1. call()方法
call方法是用于
调用
函数的方法,并且可以接收参数
1 | function.call(thisArg, arg1, arg2, ...) |
- function:要调用的函数
- thisArg:可选参数,指定函数执行时的上下文,即内部函数的this的值。如果不传,this的值将为全局对象
- agr1, arg2…:可选参数,要传递给函数的参数列表
使用
call()
方法可以方便地修改函数的执行上下文,使其在不同的对象上执行,以达到灵活性和重用性的目的。
2. es6实现call方法
- 需要满足call方法的几个条件
- 所有函数都可以调用myCall方法
- 调用原函数并且将this绑定到指定的对象
- 接收不定量的参数,并且返回结果
1 | //实现代码 |
通过给函数原型上添加myCall方法实现所有函数能够调用该方法
要改变This的指向,就需要获取原函数的引用和传入的对象
fn.myCall(obj, 2, 4, 6),我们在调用函数的时候,就
隐式绑定
了myCall方法的this值为fn函数,所以this的值就是fn函数的引用通过将该函数的引用添加到需要绑定的对象的属性上,即给thisArg添加原函数的引用,并执行,形如
obj.fn()
,隐式绑定将fn函数的this值绑定到obj对象上- 但由于设定变量来保存原函数的引用,可能会导致设置的变量与原有的对象中的属性命名冲突,缩小了命名空间
- 利用es6方法中的
symbol()
构造函数,每次调用返回一个独一无二的值,利用该特性来实现设置的变量不会与原有属性冲突
利用…args剩余参数语法,动态接收不定量的参数,并将它们作为数组存储在args中
最后利用delete关键字再删除绑定对象中的该属性
二:手写apply方法
1. apply()方法
apply()方法是调用原函数的同时可以指定原函数this的值,并传递一个参数数组
1 | function.apply(thisArg, [argsArray]) |
- function: 原函数
- thisArg:可选参数,指定函数执行时的上下文,即内部函数的this的值。如果不传,this的值将为全局对象
- [argsArrray]:一个数组或类数组对象,包含了要传递给函数的参数。
2. es6实现apply方法
- apply方法与call方法区别就是接收参数的形式不同
- call方法接收参数是不定参数,接收时候就需要用到es6的剩余参数
- apply方法传递的是一个参数数组,只需要在调用原函数的时候,利用展开运算符将数组展开传递参数即可
1 | Function.prototype.myApply = function (thisArg, args) |
三:手写bind方法
1. bind()方法
bind方法用于创建一个新函数,并给指定对象绑定原函数的this的值,并在调用的时候传递给Bind()方法的参数作为新函数的预置参数
1 | function.bind(thisArg[, arg1[, arg2[, ...]]]) |
thisArg
:在新函数中被绑定为this
值的对象。arg1, arg2, ...
:作为新函数的预置参数,可选。
2. es6实现bind方法
- 创建一个新函数,即返回一个函数
- 利用call或apply方法绑定this的值
- 通过展开运算符
...
将args1
(bind()
方法的第二个及后续参数)和args2
(新函数的参数)合并为一个数组,然后传递给apply()
方法。
1 | Function.prototype.myBind = function (thisArg, ...args1) |