JS前端面试题详解之手写bind

目录
  • bind 的用法
  • this 的指向问题
  • 积累参数
  • 实现一个 bind
  • 结尾

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

bind 的用法

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

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

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

接受的参数为如下。

  • 第 1 个参数 thisArg:用于修改 this 指向,且 this 一旦修改后将无法再改变。
  • 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 指向是在执行时确定的

  • 如果函数是 bind 返回的,this 永远指向执行 bind 绑定的那个 thisArg 值;
  • 如果函数前面有个对象,那 this 指向这个对象;
  • 如果函数前没有对象,那 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 原函数的返回值)。

到此这篇关于JS前端面试题详解之手写bind的文章就介绍到这了,更多相关JS手写bind内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaScript手写call,apply,bind方法

    目录 前言 改写this实现思路 前期准备 手写call方法 手写apply方法 手写bind方法 前言 改变this指向在书写业务的时候经常遇到,我们经常采用以下方法进行改写 使用作用声明变量存储this 使用jJavaScript的原生方法call,apply,以及bind进行改写 第一种方法就不说了,就是一个变量存储的问题,主要说第二种如何实现的 call,bind,apply方法都是JavaScript原生的方法,挂载在Function原型上,使得所有函数都可以调用,今天我们来实现一下c

  • 使用JS简单实现apply、call和bind方法的实例代码

    目录 1.方法介绍 2.apply.call和bind方法的实现 2.1.apply的实现 2.2.call的实现 2.3.bind的实现 总结 1.方法介绍 apply.call和bind都是系统提供给我们的内置方法,每个函数都可以使用这三种方法,是因为apply.call和bind都实现在了Function的原型上(Function.prototype),而他们的作用都是给我们函数调用时显式绑定上this.下面先介绍一下它们的基本用法: apply方法:调用一个具有给定this值的函数,以及

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

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

  • 使用 js 简单的实现 bind、call 、aplly代码实例

    这篇文章主要介绍了使用 js 简单的实现 bind.call .aplly代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Function.prototype._call = function(obj,...arg){ var me = this; var k = Symbol("test"); //生成唯一的 key obj[k] = me; var result = obj[k](...arg); delete obj[k

  • Javascript动手实现call,bind,apply的代码详解

    1.检查当前调用的是否为函数 2.如果当前没有传入指向的this,则赋值为window 3.将fn指向当前调用的函数 4.获取传入的参数 5.将参数传入fn进行调用 6.将对象上的fn删除 7.返回结果 //普通call的实现 function hello(){ console.log('hello 我是'+this.name); }; let person = { name:'krys' }; var name = 'liang';//只有var的变量属于window hello();// '

  • 原生js代码能实现call和bind吗

    js手动实现call和bind都是谎言 网上有很多关于说自己实现call和bind的原理的文章,然而call和bind的原理真如他们所说的那样吗?今天就让我来推翻这些所谓的"原理",揭开谎言下的真相. 首先看看网上对call的实现: // 手写 call Function.prototype.mycall = function (context) { context = context || window; context.fn = this; const args = [...arg

  • JS前端面试题详解之手写bind

    目录 bind 的用法 this 的指向问题 积累参数 实现一个 bind 结尾 大家好,我是前端西瓜哥,今天我们用 JS 来实现内置的 bind 方法. bind 的用法 在实现之前,我们先学习一下 Function.prototype.bind 的用法. function.bind(thisArg[, arg1[, arg2[, ...]]]) bind 是函数特有的一个方法,可以创建一个绑定了 this 的新函数. 接受的参数为如下. 第 1 个参数 thisArg:用于修改 this 指

  • 万字详解JavaScript手写一个Promise

    目录 前言 Promise核心原理实现 Promise的使用分析 MyPromise的实现 在Promise中加入异步操作 实现then方法的多次调用 实现then的链式调用 then方法链式调用识别Promise对象自返回 捕获错误及 then 链式调用其他状态代码补充 捕获执行器错误 捕获then中的报错 错误与异步状态的链式调用 将then方法的参数变成可选参数 Promise.all方法的实现 Promise.resolve方法的实现 finally方法的实现 catch方法的实现 完整

  • js前端面试题及答案整理(一)

    Part1 手写代码 现场手写代码是现在面试中很常见的一类面试题,考察基础的数据结构与算法能力. 1 数组去重的实现 基本数组去重 Array.prototype.unique = function(){ var result = []; this.forEach(function(v){ if(result.indexOf(v) < 0){ result.push(v); } }); return result; } •利用hash表去重,这是一种空间换时间的方法 Array.prototyp

  • 详解PyTorch手写数字识别(MNIST数据集)

    MNIST 手写数字识别是一个比较简单的入门项目,相当于深度学习中的 Hello World,可以让我们快速了解构建神经网络的大致过程.虽然网上的案例比较多,但还是要自己实现一遍.代码采用 PyTorch 1.0 编写并运行. 导入相关库 import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, t

  • JS手写bind之处理new的情况详解

    目录 new 判断函数是否通过 new 被调用 new 和 bind 实现完整的 bind 结尾 大家好,我是前端西瓜哥. 之前写了一篇关于 JS 中 bind 方法的实现的文章,并给出了实现: Function.prototype.myBind = function(thisArg, ...prefixArgs) { const fn = this; return function(...args) { return fn.call(thisArg, ...prefixArgs, ...arg

  • js正则表达式常用函数详解(续)

    正则表达式对象的方法 1.test,返回一个 Boolean 值,它指出在被查找的字符串中是否存在模式.如果存在则返回 true,否则就返回 false. 2.exec,用正则表达式模式在字符串中运行查找,并返回包含该查找结果的一个数组. 3.compile,把正则表达式编译为内部格式,从而执行得更快. 正则表达式对象的属性 1.source,返回正则表达式模式的文本的复本.只读. 2.lastIndex,返回字符位置,它是被查找字符串中下一次成功匹配的开始位置. 3.input ($_),返回

  • for循环 + setTimeout 结合一些示例(前端面试题)

    一.背景 最近在翻看以前的老书<node.js开发指南>,恰好碰到 for 循环 + setTimeout 的经典例子,于是重新梳理了思路并记录下. 二.写在前面,setTimeout 和 setInterval 的执行机制 在日常编码中,你会发现,给 setTimeout 和 setInterval 设定延迟时间往往并不准,或者干脆 setTimeout(function(){xxx},0) 也不是立马执行(特别是有耗时代码在前),这是因为 js 是单线程的,有一个事件队列机制,setTim

  • 整理一些最近经常遇到的前端面试题

    前言 本文主要整理了一些最近遇到的前端面试题,方便大家在面试前有所准备,文中给出了详细的解答,下面话不多说了,来看看详细的介绍吧. 1.标签属性中title和alt的区别 答: title是设置鼠标移动到图片上时显示的内容,而alt是用于当图片没有正常显示时出现的提示文字,另外alt还用于在seo中针对图片的优化说明. 2.隐藏元素的几种方法 答: 1.display:none; 2.visibility:hidden; 3.opacity:0; 4.position:absolute; lef

  • 基于node.js之调试器详解

    1.在命令行窗口中,可以使用"node debug" 命令来启用调试器,代码如下: node debug<需要被执行的脚本文件名>接下来根据一个实例进行学习调试过程: 编写app.js文件进行调试: console.log('hello,word') function foo(){ console.log('hello,foo') return 100; } var bar = 'This is a pen'; var http = require('http') var

  • JS之相等操作符详解

    1.相等 == 和不相等 != 先转换操作数再比较相等性 在转换不同的数据类型时,相等和不相等遵循以下规则: 1.1 如果有一个操作数是布尔值,则在比较相等性前先将其转换为数值---false转换为0,true转换为1; 1.2 如果一个操作数是字符串,另一个操作数是数值,则在比较相等性前将字符串转换为数值 1.3 如果一个操作数是对象昂,另一个不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则比较 1.4 null和undefined是相等的 1.5 在比较相等性之前,

随机推荐