JavaScript高级用法(5)

JavaScript高级用法(5)
最新回答
小昊昊

2026-05-27 21:46:40

学习课程目标:

1、手动实现call和apply方法

2、手动实现bind方法

知识要点:1、手动实现call和apply方法

1.1 手写call

call():在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。

注意两点:第一步

上述方式等同于:

这个时候this就指向了foo,但是这样却给foo对象本身添加了一个属性,所以我们用delete再删除它即可。

所以我们需要模拟的步骤可以分为:

以上个例子为例,就是:

根据上述思路,提供一版:

1.1.2 第二步

call除了可以指定this,还可以指定参数

可以从 Arguments 对象中取值,取出第二个到最后一个参数,然后放到一个数组里。

上述代码的 Arguments 中取到第二个到最后一个参数。

接下来用eval拼接成一个函数;考虑到目前大部分浏览器在console中限制eval的执行,也可以使用rest

此处代码为:

1.1.3 第三步

举例:

2. 针对函数,可以实现返回值

这里继续对call2方法进行优化:

es6后该方法的写法可以简化为:

2、手动实现apply

apply 的实现和 call 类似,只是入参不同而已,apply的入参为一个数组。

es6后该方法的写法可以简化为:

2、手动实现bind方法

bind() 方法会创建一个新函数。当这个函数被调用时,bind() 的第一个参数将作为它运行似的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。

由此我们可以首先得出 bind 函数的两个特点;

2.1 返回函数的模拟实现

关于指定 this 的指向,我么可以先使用 call 或者 apply 实现

2.2 传参的模拟实现

接下来,关于参数的传递:

当需要传 name 和 age 两个参数时, 可以在 bind 的时候,只传一个 name,在执行返回的函数的时候,再传另一个参数age。

这里如果不适用reset,使用arguments进行处理:

2.3 构造函数效果的模拟实现

bind还有一个特点,就是

一个绑定函数也能使用 new 操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。

也就是说当 bind 返回的函数作为构造函数时,bind 时指定的 this 值会失效,但传入的参数依然生效。

举个例子:

尽管在全局和 foo 中都声明了 value值,最后依然返回了 undefined,说明绑定的 this 失效了。

后文中 new 的模拟实现,就会知道这个时候的 this 已经指向了 obj。

2.4 构造函数效果的优化实现

在这个写法中,我们直接将 fBound.prototype = this.prototype,我们直接改 fBound.prototype 的时候,也会直接修改绑定函数的prototype。这个时候,我们可以通过一个空函数来进行中转:

2.5 最终版

调用 bind 的不是函数时,提示错误:

最终代码为: