前言
apply && bind
apply && bind 作用
相同点 VS 不同点
轻松手写
手写实现 apply
手写实现 bind
总结
前言面试官问:“聊一聊你理解的 apply
和 bind
。”
于是我便开始开始介绍起这两个知识点,最后顺带提了它们的实现代码。
这不提倒还好,一提就出了大事,一下子给面试官找到了面试题目。
面试官紧接着说:“既然你提到了代码,那就手写一下它俩吧。”
我一下子不知所措。虽然我了解过 apply
和 bind
手写代码,但是现在让我立马手写出来它们,实属有些困难。
不过最后还是硬着头皮写了一下,但是结果不尽人意。
apply && bind函数 apply
和 bind
在日常开发中经常会被用到,理解它们的作用以及逻辑至关重要。所以今天我们来探讨一下它们的实现逻辑,并对它们进行手写,来学会如何轻松手写它们。
知己知彼,方能百战百胜。在进行手写之前,我们先来简单聊一下它们。 众所周知,apply 和 bind 作用是改变函数的调用对象。很多人对这个不是很理解,什么是函数的调用对象呢?其实简单点理解就是改变函数的 this
对象指向。因为这时候 this
在函数就充当了一个调用的作用,而 apply 和 bind 就是有着改变 this
指向的作用。
apply
的其他作用,是改变对象的执行上下文,并且是立即执行的。 bind
也能改变对象的执行上下文。
它们的相同点在于都可以改变 this
的指向,并且传入的第一个参数都是绑定的 this
,不同点在于 bind 返回的是一个改变了 this
指向的函数,便于稍后调用,而 apply 会立即调用。另外 apply 是一次性传入参数,而 bind 可以分为多次传入。
有了理论基础,我们可以开始手写部分了。
手写实现 apply我们先来看 apply,apply 手写实现其实很简单,大致思路如下:
首先用 typeof
来检查调用 apply
的对象是否为函数,如果不是则抛出错误。然后将函数作为传入的 context
对象的一个属性,并调用该函数。 最后调用之后通过 delete
删除该属性,避免对传入对象造成污染。context
代表上下文对象。
代码如下:
Function.prototype.apply = function (context, args) {
if (typeof this !== 'function') {
console.log('not a function')
}
const fn = Symbol()
context[fn] = this
context[fn](...args)
delete context[fn]
}
这里使用到了新的 Symbol
数据类型,主要是避免在把函数赋值给 context
对象的时候,因为属性名冲突而覆盖掉原有属性。
相比较与 apply 手写,我个人觉得 bind 手写会相对复杂一些。bind 手写实现思路如下:
和之前一样,首先判断调用对象是否为函数,然后获取其余传入参数值,并创建一个函数返回。最后根据调用方式,传入不同的绑定值。
函数内部使用 apply 来绑定函数调用,需要判断函数作为构造函数的情况,这个时候需要传入当前函数的 this
给 apply 调用,其余情况都传入指定的上下文对象 context
。
代码如下:
Function.prototype.myBind = function(context) {
if (typeof this !== "function") {
console.log("Error");
}
let args = [...arguments].slice(1),
fn = this;
return function Fn() {
return fn.apply(
this instanceof Fn ? this : context,
args.concat(...arguments)
);
};
};
总结
关于它们的手写就到这里了,相信下次再面对同样的问题时处理起来就能游刃有余了。这两个手写各有各的特点,我个人建议可以多写写 bind 的手写,我觉得它会比 apply 出错率更高。
虽然文章中是以手写 apply 和 bind 为主,但是并不缺少 js
相关知识点,比如 this
指向问题,总之,js
很重要,既是基础又是重点。
以上就是手写apply和bind实例的轻松实现详解的详细内容,更多关于apply bind手写实例的资料请关注软件开发网其它相关文章!