JS前端面试手写apply和bind实例

目录
  • 前言
  • apply && bind
    • apply && bind 作用
    • 相同点 VS 不同点
  • 轻松手写
    • 手写实现 apply
    • 手写实现 bind
  • 总结

前言

面试官问:“聊一聊你理解的 applybind。”

于是我便开始开始介绍起这两个知识点,最后顺带提了它们的实现代码。

这不提倒还好,一提就出了大事,一下子给面试官找到了面试题目。

面试官紧接着说:“既然你提到了代码,那就手写一下它俩吧。”

我一下子不知所措。虽然我了解过 applybind 手写代码,但是现在让我立马手写出来它们,实属有些困难。

不过最后还是硬着头皮写了一下,但是结果不尽人意。

apply && bind

函数 applybind 在日常开发中经常会被用到,理解它们的作用以及逻辑至关重要。所以今天我们来探讨一下它们的实现逻辑,并对它们进行手写,来学会如何轻松手写它们。

apply && bind 作用

知己知彼,方能百战百胜。在进行手写之前,我们先来简单聊一下它们。 众所周知,apply 和 bind 作用是改变函数的调用对象。很多人对这个不是很理解,什么是函数的调用对象呢?其实简单点理解就是改变函数的 this 对象指向。因为这时候 this 在函数就充当了一个调用的作用,而 apply 和 bind 就是有着改变 this 指向的作用。

apply 的其他作用,是改变对象的执行上下文,并且是立即执行的。 bind 也能改变对象的执行上下文。

相同点 VS 不同点

它们的相同点在于都可以改变 this 的指向,并且传入的第一个参数都是绑定的 this,不同点在于 bind 返回的是一个改变了 this 指向的函数,便于稍后调用,而 apply 会立即调用。另外 apply 是一次性传入参数,而 bind 可以分为多次传入。

轻松手写

有了理论基础,我们可以开始手写部分了。

手写实现 apply

我们先来看 applyapply 手写实现其实很简单,大致思路如下:

首先用 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 对象的时候,因为属性名冲突而覆盖掉原有属性。

手写实现 bind

相比较与 apply 手写,我个人觉得 bind 手写会相对复杂一些。bind 手写实现思路如下:

和之前一样,首先判断调用对象是否为函数,然后获取其余传入参数值,并创建一个函数返回。最后根据调用方式,传入不同的绑定值。

函数内部使用 apply 来绑定函数调用,需要判断函数作为构造函数的情况,这个时候需要传入当前函数的 thisapply 调用,其余情况都传入指定的上下文对象 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手写实例的资料请关注我们其它相关文章!

(0)

相关推荐

  • JS 函数的 call、apply 及 bind 超详细方法

    目录 JS 函数的 call.apply 及 bind 方法 一.call() 方法 1.call()方法的模拟实现 二.apply() 方法 1.apply()方法的模拟实现 三.bind() 方法 1.bind() 方法的模拟实现 四.总结 JS 函数的 call.apply 及 bind 方法 一.call() 方法 调用 call() 方法会立即执行目标函数,同时改变函数内部 this 的指向.this 指向由方法的第一个参数决定,后面逐个列举的任意个参数将作为目标函数的参数一一对应传入

  • 浅谈JavaScript中的apply/call/bind和this的使用

    fun.apply(context,[argsArray]) 立即调用fun,同时将fun函数原来的this指向传入的新context对象,实现同一个方法在不同对象上重复使用. context:传入的对象,替代fun函数原来的this: argsArray:一个数组或者类数组对象,其中的数组参数会被展开作为单独的实参传给 fun 函数,需要注意参数的顺序. fun.call(context,[arg1],[arg2],[-]) 同apply,只是参数列表不同,call的参数需要分开一个一个传入.

  • 原生js如何实现call,apply以及bind

    1.实现call 步骤: 将函数设为对象的属性: 指定this到函数,并传入给定参数执行函数: 执行之后删除这个函数: 如果不传入参数,默认指向window: Function.prototype.mycall = function (context, ...args) { //判断是否为函数,如果不是函数,则报错 if (typeof this !== "function") { throw new Error("不是函数"); } context = conte

  • JavaScript函数之call、apply以及bind方法案例详解

    总结 1.相同点 都能够改变目标函数执行时内部 this 的指向 方法的第一个参数用于指定函数执行时内部的 this 值 支持向目标函数传递任意个参数 若不向方法的第一个参数传值或者传递 undefined.null,则在 JavaScript 正常模式下,目标函数内部的 this 指向 window 对象,严格模式下,分别指向 undefined.null. 2.区别 apply() 方法可接收两个参数,而 call() 和 bind() 方法则可接收多个参数. apply() 方法向目标函数

  • JavaScript中call、apply、bind实现原理详解

    目录 前言 call 用法 实现 简单的实现版本: 升级版: apply 用法 实现 bind 用法 基本版: 升级版: 总结 前言 众所周知 call.apply.bind 的作用都是'改变'作用域,但是网上对这这'改变'说得含糊其辞,并未做详细说明,'改变'是直接替换作用域?谁替换谁?怎么产生效果?这些问题如果不理解清楚,就算看过手写实现,估计也记不长久 所以本文介绍了call.apply.bind的用法和他们各自的实现原理. call call() 方法使用一个指定的 this 值和单独给

  • 详解JS中的this、apply、call、bind(经典面试题)

    这又是一个面试经典问题~/(ㄒoㄒ)/~~也是 ES5中众多坑中的一个,在 ES6 中可能会极大避免 this 产生的错误,但是为了一些老代码的维护,最好还是了解一下 this 的指向和 call.apply.bind 三者的区别. this 的指向 在 ES5 中,其实 this 的指向,始终坚持一个原理:this 永远指向最后调用它的那个对象,来,跟着我朗读三遍:this 永远指向最后调用它的那个对象,this 永远指向最后调用它的那个对象,this 永远指向最后调用它的那个对象.记住这句话

  • JS前端面试手写apply和bind实例

    目录 前言 apply && bind apply && bind 作用 相同点 VS 不同点 轻松手写 手写实现 apply 手写实现 bind 总结 前言 面试官问:“聊一聊你理解的 apply 和 bind.” 于是我便开始开始介绍起这两个知识点,最后顺带提了它们的实现代码. 这不提倒还好,一提就出了大事,一下子给面试官找到了面试题目. 面试官紧接着说:“既然你提到了代码,那就手写一下它俩吧.” 我一下子不知所措.虽然我了解过 apply 和 bind 手写代码,但是

  • 高级前端面试手写扁平数据结构转Tree

    目录 前言 什么是好算法,什么是坏算法 时间复杂度 计算方法 空间复杂度 计算方法: 不考虑性能实现,递归遍历查找 不用递归,也能搞定 最优性能 小试牛刀 前言 招聘季节一般都在金三银四,或者金九银十.最近在这五六月份,陆陆续续面试了十几个高级前端.有一套考察算法的小题目.后台返回一个扁平的数据结构,转成树. 我们看下题目:打平的数据内容如下: let arr = [ {id: 1, name: '部门1', pid: 0}, {id: 2, name: '部门2', pid: 1}, {id:

  • JS前端html2canvas手写示例问题剖析

    目录 前言 感性认识 第一步:解析 dom 树 第二步:按层叠规则分组(重点) 第三步:创建画布 第四步:渲染 另一种方法(html->svg->canvas) 结语 前言 这两天把 html2canvas 这玩意抽丝剥茧了一下,搞了个勉强能跑的小 demo,麻雀虽小五脏俱全,来看看实现的效果吧(跟基金一样的绿,离离原上谱)

  • JS前端面试数组扁平化手写flat函数示例

    目录 前言 题目 实现扁平化的方法 封装 flatten 1. ES6 flat 2. toString 3. 使用正则替换 4. 循环递归 4.1 循环 + concat + push 4.2 增加参数控制扁平化深度 4.3 巧用 reduce 4.4 使用 Generator 函数 5. 使用堆栈 stack 避免递归 6.while 循环+ some方法 前言 由于上半年参加了校招的技术面试, 前前后后面了20多个人了, 每次面试都会让应聘者手写一下数组扁平化flat(),但是发现居然没有

  • 面试手写实现Promise.all

    目录 前言 常见面试手写系列 Promise.resolve 简要回顾 源码实现 Promise.reject 简要回顾 源码实现 Promise.all 简要回顾 源码实现 Promise.allSettled 简要回顾 源码实现 Promise.race 简单回顾 源码实现 结尾 前言 (ಥ﹏ಥ)曾经真实发生在一个朋友身上的真实事件,面试官让他手写一个Promise.all,朋友现场发挥不太好,没有写出来,事后他追问面试官给的模糊评价是基础不够扎实,原理性知识掌握较少... 当然整场面试失利

  • js前端面试常见浏览器缓存强缓存及协商缓存实例

    目录 前言 搭建环境 强缓存 协商缓存 Etag和If-None-Match Last-Modify和if-modified-since 前言 最近在背面试题时,时常会看见浏览器缓存,虽然没有用过但是从它的描写中大致是知道它的作用和重要性.但是还是没有代码实操过,也是一知半解的,这口气咽不下啊,开始找资料,但是大部分都是理论半行代码没有,终于东拼西凑顿悟了.开始搭环境,干活. 浏览器缓存 浏览器缓存是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本

  • JS前端面试必备——基本排序算法原理与实现方法详解【插入/选择/归并/冒泡/快速排序】

    本文实例讲述了JS前端面试必备--基本排序算法原理与实现方法.分享给大家供大家参考,具体如下: 排序算法是面试及笔试中必考点,本文通过动画方式演示,通过实例讲解,最后给出JavaScript版的排序算法 插入排序 算法描述: 1. 从第一个元素开始,该元素可以认为已经被排序 2. 取出下一个元素,在已经排序的元素序列中从后向前扫描 3. 如果该元素(已排序)大于新元素,将该元素移到下一位置 4. 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置 5. 将新元素插入到该位置后 6. 重复

  • caffe的python接口之手写数字识别mnist实例

    目录 引言 一.数据准备 二.导入caffe库,并设定文件路径 二.生成配置文件 三.生成参数文件solver 四.开始训练模型 五.完成的python文件 引言 深度学习的第一个实例一般都是mnist,只要这个例子完全弄懂了,其它的就是举一反三的事了.由于篇幅原因,本文不具体介绍配置文件里面每个参数的具体函义,如果想弄明白的,请参看我以前的博文: 数据层及参数 视觉层及参数 solver配置文件及参数 一.数据准备 官网提供的mnist数据并不是图片,但我们以后做的实际项目可能是图片.因此有些

  • js前端面试之同步与异步问题详解

    前言 我本来是打算写一篇co源码精读(为啥读co,因为它短),然鹅发现自己存在一系列基础问题没有搞透彻,打算写一个js基础系列文章,总结自己的理解(copy),希望与你在学习路上一同进步.首先问问自己当面试官问到js中的同步和异步,这个问题该怎么回答?理解一个问题无非是what-why-how js同步和异步问题是什么-->为什么会产生异步问题-->如何解决. 一.JavaScript起源 技术的出现,和应用场景密切相关的.JavaScript诞生于1995年.当时,它的主要目的是处理以前由服

随机推荐