前端面试题:用 JS 来实现内置的 Bind 方法

更新日期: 2022-07-08 阅读: 1.8k 标签: 面试 作者: 前端西瓜哥

大家好,我是前端西瓜哥,今天我们用 JS 来实现内置的 bind 方法。

bind 的用法

在实现之前,我们先学习一下 Function.prototype.bind 的用法。

function.bind(thisArg[, arg1[, arg2[, ...]]])

bind 是函数特有的一个方法,可以创建一个绑定了 this 的新函数。

接受的参数为如下。

  1. 第 1 个参数 thisArg:用于修改 this 指向,且 this 一旦修改后将无法再改变。
  2. arg1, arg2, ...:剩余的是可选的参数项,会在 bind 返回的新函数调用时,会作为函数的前几个参数去调用。

this 的指向问题

我们在开发的时候,有时候会遇到 JS 的 this 指向丢失问题。

下面我们看一个例子。

const person = {
  nickname: '前端西瓜哥',
  eatWatermelon() {
    console.log(this.nickname + ' 吃西瓜');
  }
};
person.eatWatermelon();

上面的代码中,在调用 person.eatWatermelon 时,this 指向 person,输入结果为  前端西瓜哥 吃西瓜 。

下面我们再执行下面代码。

const eatWatermelon = person.eatWatermelon;
eatWatermelon();

输入结果就匪夷所思了起来,它是: undefined 吃西瓜。

这是因为 this 的指向变成了  eatWatermelon() 执行时所在作用域的 this,在浏览器 script 标签最外层时,是全局对象 window(严格模式下,全局对象 this 会变成 undefined)。

所以  eatWatermelon() 执行中的 this.nickname 等价于 window.nickname,因为我们没有赋值过,所以是 undefined。

有时候我们不希望 this 丢失,该怎么办?

这时候我们就要用到一个 bind 方法,可以永久改变 this 的指向,且不能再改变。

const eatWatermelon = person.eatWatermelon.bind(person);
eatWatermelon();

这样的话,eatWatermelon 函数的 this 就会永远指向 person,能输出我们预期的  前端西瓜哥 吃西瓜 。

所 以,对于一个函数来说,它的 this 指向是在执行时确定的:

  1. 如果函数是 bind 返回的,this 永远指向执行 bind 绑定的那个 thisArg 值。
  2. 如果函数前面有个对象,那 this 指向这个对象。
  3. 如果函数前没有对象,那 this 指向当前的作用域(可能是函数作用域,可能是全局作用域)。

另一种控制 this 指向的写法是使用  箭头函数 ,尤其适合在函数中调用另一个函数的情况,因为篇幅原因这里不展开讲。

积累参数

bind 除了常用于强绑 this 外,另一个用的比较少的作用:预置函数参数。

function add(a, b, c) {
  return a + b + c;
}
const addSix = add.bind(null, 6);
const addSixThenAddFour = addSix.bind(null, 4);
addSixThenAddFour(5)
// 15
addSixThenAddFour(7)
// 17

实现一个 bind

下面进入正题,实现一个 bind。

Function.prototype.myBind = function(thisArg, ...prefixArgs) {
  const fn = this;
  return function(...args) {
    return fn.call(thisArg, ...prefixArgs, ...args);
  }
}

要点是利用 闭包。

让返回的新函数可以访问到三个私有属性:

  • fn(原来的函数)。
  • thisArg(需要强绑不变的 this 指向)。
  • prefixArgs 属性。

当我们调用这个新函数时,我们会执行 fn 函数,并利用 call 方法来指定 this 为 thisArg,然后将预填充的多个参数,和新函数接收的参数依次填入。

最后不要忘记返回调用后的值。因为新函数是原函数的封装,返回值也要和原函数表现一致。

结尾

bind 方法的实现并不复杂,更重要的是你要先掌握好 bind 的用法。

就好比做业务需求一样,不明确需求,就容易产生 bug,

然后需要你对闭包有一定的认识,知道如何去保存私有变量,以及封装函数的写法(记得 return 原函数的返回值)。

来源:https://www.toutiao.com/article/7117667580352938508

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/11871

相关推荐

有趣的Js面试题_如何让 (a == 1 && a == 2 && a == 3) 返回 true

题目大意为:JS 环境下,如何让 a == 1 && a == 2 && a == 3 这个表达式返回 true ?这道题目乍看之下似乎不太可能,因为在正常情况下,一个变量的值如果没有手动修改,在一个表达式中是不会变化的。

前端面试之webpack面试常见问题

什么是webpack和grunt和gulp有什么不同?什么是bundle,什么是chunk,什么是module?什么是Loader?什么是Plugin?如何可以自动生成webpack配置?webpack-dev-server和http服务器如nginx有什么区别?

Web前端年后跳槽面试复习指南

很多童鞋可能年后有自己的一些计划,比如换份工作环境,比如对职业目标有了新的打算。当然面试这一关不得不过,大概又不可能系统性的复习,这里罗列一些 重点 面试的知识点和文章,

React常见面试题

React常见面试题:React中调用setState之后发生了什么事情?React中Element与Component的区别?优先选择使用ClassComponent而不是FunctionalComponent?React中的refs属性的作用是什么?React中keys的作用是什么?

毕业一年左右的前端妹子面试总结

把面试当做学习,这个过程你会收益很大。前端知识很杂,可能实际工作中用到的技术,像框架都是跟着公司的要求走的,像我最近也在看React啦,Vue和React都对比着再学习

js练习笔记:10道JavaScript题目

10道JavaScript题目:累加函数addNum、实现一个Person类、实现一个arrMerge 函数、实现一个toCamelStyle函数、setTimeout实现重复调用、实现一个bind函数、实现一个Utils模块、输出一个对象自身的属性

写给程序员的 HR 面试指南

首先,切记不要诋毁你的老东家。你应该把你的离职原因集中表述在“寻找新机会或新的平台”以及尝试在新的岗位上提升自己。当然,这样的回答对于一般职位的应聘者来说不会造成减分

一篇文章教会你面试中的小套路

面试,一个短时间内对某个人做出判断的测试。很多时候,工程师们只准备了相关的技术点,却没有对非技术的软实力部分做准备。而软实力的考察,不仅贯穿整个面试流程中,更在BOSS面和HR面中尤为关键。鉴于当前业界也没有特别契合的攻略文档,仅有有几篇文章还是HR写的,特有此文

CSS 面试知识点总结

最近在整理 CSS 的时候发现遇到了很多面试中常见的面试题,本部分主要原作者在 Github 等各大论坛收录的 CSS 相关知识和一些相关面试题时所做的笔记,分享这份总结给大家,对大家对 CSS 的可以来一次全方位的检漏和排查

vue面试时需要准备的知识点

vue上手可以说是比较轻松而且简单,如果你用过angular,react,你也会很喜欢vue。vue的核心思想依旧是:构建用户界面的渐进式框架,关注视图的变化。这也是为什么新建的文件是结构是template script style

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!