引言

内容速递

看了本文您能了解到的知识!

在本篇文章中,将带你了解什么是bindbind的用途如何手写bind以及工作中实际使用bind的场景

在JavaScript中,bind()方法是用来创建一个新函数,并将其绑定到指定的对象上,从而在调用该函数时确保函数中的this关键字指向绑定的对象。

1、什么是bind

bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被指定 bind()的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

MDN文档Function.prototype.bind()

2、bind的语法

语法:

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

参数:

  • thisArg:被绑定到函数上的对象,即当调用绑定后的函数时,函数中的this关键字会指向该对象。如果thisArg参数为nullundefined,则this关键字将指向全局对象(在浏览器中通常是window对象)。

  • arg1, arg2, ...:要传递给函数的参数。这些参数将按照顺序传递给函数,并在调用函数时作为函数参数使用。

返回值:

返回一个原函数的拷贝,并拥有指定的this值和初始参数。

3、浅试一下bind

代码:

this.name = 'guizimo'
let obj = {
name: 'zimo',
getName: function() {return this.name}
} console.log(obj.getName()) // zimo let newGetName = obj.getName
console.log(newGetName()) // guizimo let bindGetName = newGetName.bind(obj)
console.log(bindGetName()) // zimo

简述代码:

  1. 第一次打印zimo,可以理解为是打印对象内的一个属性,此时的this是指向obj对象

  2. 第二次打印guizimo,因为当前环境是对象外,因为当前执行的函数是newGetName(),因此函数内部的this指向全局对象。

  3. 通过bind生成一个新的拷贝函数,当前执行的函数bindGetName()this指向obj对象

4、手写bind

这是面试官最喜欢的环节了

思路:

  • bind()方法返回一个新函数,因此需要定义一个函数来返回新函数。
  • 在新函数中,需要使用apply()call()方法来调用原始函数并传递正确的this值和参数。
  • 新函数需要接受一个thisArg参数来指定要绑定的对象,并可以接受任意数量的其他参数。

代码:

/**
* 手写bind
* @returns {function(): any}
*/
Function.prototype.myBind = function () {
// 处理函数
let args = Array.from(arguments);
let thisArg = args.shift();
// 暂存this
let thisFunc = this;
// 因为需要构造函数,所以不能是匿名函数了
const fBound = function () {
const newArgs = args.concat(Array.from(arguments));
// 判断是否为构造函数
thisArg = this instanceof fBound ? this : thisArg;
return thisFunc.apply(thisArg, newArgs);
}
// 直接将原函数的prototype赋值给绑定函数
fBound.prototype = this.prototype;
// 返回
return fBound;
}

简述代码:

  1. 通过Array.from()arguments转化为数组对象,通过shift()取出thisArg
  2. 使用thisFunc暂存当前函数的this
  3. 创建一个闭包函数fBoundnewArgs接收合并处理的arguments
  4. 判断fBound是否为构造函数,如果是构造函数,返回闭包的this,反之,返回外部拿到的thisArg,使用thisArg来接收。
  5. 使用thisFunc.apply传递thisArg值和参数newArgs
  6. 直接将原函数的prototype赋值给fBound
  7. 返回fBound

5、使用场景

5.1、创建绑定函数

这是bind最基本的一种使用方式了,也就是创建一个新的函数

代码:

this.name = 'guizimo'
let obj = {
name: 'zimo',
getName: function() {return this.name}
} console.log(obj.getName()) // zimo let newGetName = obj.getName
console.log(newGetName()) // guizimo let bindGetName = newGetName.bind(obj)
console.log(bindGetName()) // zimo

简述代码:

  1. 第一次打印zimo,可以理解为是打印对象内的一个属性,此时的this是指向obj对象
  2. 第二次打印guizimo,因为当前环境是对象外,因为当前执行的函数是newGetName(),因此函数内部的this指向全局对象。
  3. 通过bind生成一个新的拷贝函数,当前执行的函数bindGetName()this指向obj对象

5.2、创建偏函数

如果需要创建一个自定义函数,需要固定部分参数,那么bind就有它独特的作用了

代码:

function add (a, b) {
return a + b
} const res1 = add(1, 2)
console.log(res1) // 3 // 创建一个偏函数,将1作为预设的参数
const addP = add.bind(null, 1) const res2 = addP(2)
console.log(res2) // 3 const res3 = addP(3)
console.log(res3) // 4 const res4 = addP(4)
console.log(res4) // 5

简述代码:

  1. 创建了一个add 函数,调用add(1, 2),正常打印3
  2. 创建一个偏函数addP,将1作为预设的参数,调用addP(2),也可以正常打印3,后续调用addP(3)addp(4),皆打印正确的数值,实现了对一个参数的固定

6、在工作中有遇到bind的使用场景吗

6.1、React中bind的场景

JSX中传递的事件不是一个字符串,而是一个函数(如:onClick={this.handleClick}),此时onClick即是中间变量,所以处理函数中的this指向会丢失。

代码:

<button onClick={this.handleClick.bind(this)}>点击</button>

//此时this指向是当前实例对象
handleAdd = () => {
console.log(this)
this.setState({
...
})
}

解决这个问题就是给调用函数时bind(this),从而使得无论事件处理函数如何传递,this指向都是当前实例化对象。或者使用箭头函数声明一个函数,这样函数内的this也是指向当前实例。

6.2、在事件处理程序中访问事件目标的this值

在JavaScript中,需要在事件处理程序中访问事件目标的this值。在这种情况下,可以使用bind()方法将事件处理程序绑定到事件目标上,以便在调用事件处理程序时,this关键字始终指向事件目标。

代码:

const button = document.querySelector('#myButton');
button.addEventListener('click', function() {
// 在这里可以使用 this 访问按钮元素的属性和方法
}.bind(button));

博客说明与致谢

文章所涉及的部分资料来自互联网整理,其中包含自己个人的总结和看法,分享的目的在于共建社区和巩固自己。

引用的资料如有侵权,请联系本人删除!

感谢勤劳的自己个人博客GitHub,公众号【归子莫】,小程序【子莫说】

如果你感觉对你有帮助的话,不妨给我点赞鼓励一下,好文记得收藏哟!

幸好我在,感谢你来!

【JavaScript】你真的熟悉bind吗的更多相关文章

  1. JavaScript 你真的了解this指向吗

    JavaScript 你真的了解this指向吗 前言 终于开始写this指向了,相信这对很多JavaScript的学习者来说是一个非常恐怖的环节,个人认为也算是JavaScript中最难理解的一个知识 ...

  2. javascript中call,apply,bind的用法对比分析

    这篇文章主要给大家对比分析了javascript中call,apply,bind三个函数的用法,非常的详细,这里推荐给小伙伴们.   关于call,apply,bind这三个函数的用法,是学习java ...

  3. JavaScript - call() , apply() and bind()

    参考 https://www.codementor.io/niladrisekhardutta/how-to-call-apply-and-bind-in-javascript-8i1jca6jp h ...

  4. 理解javascript里的ABC--apply bind call

    一,三者共同点 js中的apply,call,bind是对于初学者比较难的概念之一,比如说我..参考几篇文章之后,统一来讲, 1.这三个函数都属于Function.prototype下面的方法,如下图 ...

  5. 你真的熟悉background吗?

    一两个月没更新博客了,因为放假刚在深圳找了实习,一直都比较忙碌,不过我觉得再忙,还是需要时间去沉淀一些东西,工作的时候别人看到的只是你有没有实现最终的结果,但自己是否思考,是否去总结,决定着你工作是否 ...

  6. JavaScript 之 call apply bind

    关键字 this 绑定的方法 this的动态切换,固然为JavaScript创造了巨大的灵活性,但也使得编程变得困难和模糊.有时,需要把this固定下来,避免出现意想不到的情况.JavaScript提 ...

  7. Javascript 中apply call bind

    在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. 先来一个例子: functi ...

  8. JavaScript中call,apply,bind方法的总结。

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...

  9. JavaScript中call,apply,bind方法的总结

    原文链接:http://www.cnblogs.com/pssp/p/5215621.html why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之 ...

  10. javascript中apply,call,bind区别,bind兼容等问题总结

    1 三者的相似之处: (1).都是用来改变函数的this对象的指向的 (2).都是用第一个参数来做this对象的指向 (3).都可以传参数进去 那么,具体到它们有什么区别呢?请看下面的例子: 两个对象 ...

随机推荐

  1. 项目中统计SQL执行缓慢的方案-数据预处理

    使用场景: 由于表数据量巨大,导致一些统计相关的sql执行非常慢,使用户有非常不好的体验,并且sql和数据库已经没有优化空间了.(并且该统计信息数据实时性要求不高的前提下) 解决方案: 整体思路:创建 ...

  2. es6的Symbol数据类型

    ES6引入了一种新的原始数据类型Symbol,表示独一无二的值.它是JavaScript语言的第七种数据类型,前六种是:Undefined.Null.布尔值(Boolean).字符串(String). ...

  3. [人脸活体检测] 论文:Face Anti-Spoofing Using Patch and Depth-based CNNs

    Face Anti-Spoofing Using Patch and Depth-based CNNs 这篇文章是人脸防伪领域比较容易理解,适合入手的一篇,主要运用到了两个CNN网络,根据输入图像的细 ...

  4. [OpenCV-Python] 7 把鼠标当画笔

    文章目录 OpenCV-Python: II OpenCV 中的 Gui 特性 7 把鼠标当画笔 7.1 简单演示 7.2 高级一点的示例 OpenCV-Python: II OpenCV 中的 Gu ...

  5. 2023-03-06:给定一个二维网格 grid ,其中: ‘.‘ 代表一个空房间 ‘#‘ 代表一堵 ‘@‘ 是起点 小写字母代表钥匙 大写字母代表锁 我们从起点开始出发,一次移动是指向四个基本方向之

    2023-03-06:给定一个二维网格 grid ,其中: '.' 代表一个空房间 '#' 代表一堵 '@' 是起点 小写字母代表钥匙 大写字母代表锁 我们从起点开始出发,一次移动是指向四个基本方向之 ...

  6. 2021-03-05:go中,io密集型的应用,比如有很多文件io,磁盘io,网络io,调大GOMAXPROCS,会不会对性能有帮助?为什么?

    2021-03-05:go中,io密集型的应用,比如有很多文件io,磁盘io,网络io,调大GOMAXPROCS,会不会对性能有帮助?为什么? 福哥答案2021-03-05: 这是面试中被问到的.实力 ...

  7. 2021-08-30:给定两个字符串str1和str2,在str1中寻找一个最短子串,能包含str2的所有字符,字符顺序无所谓,str1的这个最短子串也可以包含多余的字符。返回这个最短包含子串。

    2021-08-30:给定两个字符串str1和str2,在str1中寻找一个最短子串,能包含str2的所有字符,字符顺序无所谓,str1的这个最短子串也可以包含多余的字符.返回这个最短包含子串. 福大 ...

  8. KubeCon EU 2023 落幕,哪些技术趋势值得关注?

    KubeCon+CloudNativeCon 是云原生领域的技术盛会,上个月月末,在荷兰阿姆斯特丹举办的欧洲 KubeCon+CloudNativeCon 刚刚落下帷幕,此次大会吸引了10000多名参 ...

  9. WSGI实现一个WEB服务

  10. Linux:论如何在虚拟机上挂载多个镜像?

    欢迎来到千汐   博客名称:千秋云染博客网址:https://www.cnblogs.com/skyrainmom 寄语:在混乱不堪的世界里你只管前行,时间替会证明一切 world cookie 我可 ...