call、apply 以及 bind 的区别和用法

您所在的位置:网站首页 call和answer的区别 call、apply 以及 bind 的区别和用法

call、apply 以及 bind 的区别和用法

2024-06-02 03:52| 来源: 网络整理| 查看: 265

 目录

一、函数用法

1.call用法

2.apply用法 

3.bind用法

二、手写源码实现 

1.手写call函数

2.手写apply函数

3.手写bind函数

三、区别以及使用场景

1.相同点 

2.不同点

3.使用场景 

相信很多同学在面试中遇到这样的问题,今天我们就彻底搞懂JavaScript中的call、apply、 bind的用法、实现以及三者之间的区别,废话不多说,直接开撸!

一、函数用法

call,apply,bind 都是函数 Function 原型上的方法,三者的功能都是用来改变函数中的 this 指向。下面我们分别介绍下这三个函数用法。

1.call用法

call() 方法是预定义的 JavaScript 方法。它可以用来调用所有者对象作为参数的方法。通过 call(),您能够使用属于另一个对象的方法。

案列:

const person = { fullName: function () { return this.firstName + this.lastName } } const newPerson = { firstName: "fu", lastName: "chaoyang", } person.fullName.call(newPerson) // fuchaoyang

 传参:

call传入的参数数量不固定,第一个参数代表函数内的this指向,从第二个参数开始往后,每个参数被依次传入函数。 

const person = { fullName: function (country, city) { return this.firstName + this.lastName + " " + country + " " + city } } const newPerson = { firstName: "fu", lastName: "chaoyang", } person.fullName.call(newPerson, 'china', 'xian') // fuchaoyang china xian

call是包装在apply上面的一颗语法糖,如果我们明确知道函数接受多少个参数,而且想一目了然的表达形参和实参的对应关系,那么我们可以用call来传达参数。

2.apply用法 

apply接受两个参数,第一个参数指定了函数体内的this指向。第二个参数为一个带下标的集合,这个集合可以为数组,也可以为类数组,apply方法把这个集合中的元素作为参数传递给被调用的函数。

案列:

const person = { fullName: function (country, city) { return this.firstName + this.lastName + " " + country + " " + city } } const newPerson = { firstName: "fu", lastName: "chaoyang", } person.fullName.apply(newPerson, ['china', 'xian']) // fuchaoyang china xian

这段代码中参数china,xian被放在数组中一起传给了person的fullName函数,分别对应fullName函数中的country,city参数。

当调用一个函数时,js的解释器并不会计较形参和实参在数量,类型以及顺序上的区别,js在内部就是用一个数组来表示的。从这个意义上来说,call比apply使用率更高,我们不必关心多少参数被传入函数,只要用apply一股脑推进去就行了。

 3.bind用法

相信大家在使用React调用函数的时候必须使用bind(this),后直接在class中声明函数即可正常使用,但是为什么要使用这个呢?

bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()中的第一个参数的值,例如:f.bind(obj),实际上可以理解为obj.f(),这时f函数体内的this自然指向的是obj;

const person = { fullName: function (country, city) { return this.firstName + this.lastName + " " + country + " " + city } } const newPerson = { firstName: "fu", lastName: "chaoyang", } person.fullName.bind(newPerson, 'china', 'xian') // 打印出fullName函数 person.fullName.bind(newPerson, 'china', 'xian')() // fuchaoyang china xian

bind传参和call是一致的,内部实现是先把当前函数保存起来,然后返回一个新的函数,当我们将来要执行当前函数时,实际返回的是刚刚返回的新的fullName函数。它不会立即执行,而是需要的时候调用即可。

二、手写源码实现  1. 手写call函数 // call实现 Function.prototype.myCall = function (context) { context = context || window const arg = [...arguments].slice(1) const fn = Symbol() context[fn] = this const result = context[fn](...arg) delete context[fn] return result } 2.手写apply函数 // apply 实现 Function.prototype.myApply = function (context, args) { context = context || window // 默认 window args = [...args] // 参数 const fn = Symbol() // 给 context 设置一个独一无二的属性,避免覆盖原有属性 context[fn] = this // 这里的 this 指向调用它的函数fn const result = context[fn](...args) // 调用之 delete context[fn] // 删除添加的属性 return result // 返回值 } 3.手写bind函数 // bind 实现 Function.prototype.myBind = function (context) { context = context || window // 默认 window const args = [...arguments].slice(1) // 参数 const fn = this // 这里的 this 指向调用它的函数 fn return function () { return fn.apply(context, args) } } 三、区别以及使用场景 1.相同点  bind、call、apply都是用来指定一个函数内部的this的值。 接收的第一个参数都是this要指向的对象。都可以利用后续参数传参。 2.不同点 call和bind传参相同,多个参数依次传入的。apply只有两个参数,第二个参数为数组。call和apply都是对函数进行直接调用,而bind方法不会立即调用函数,而是返回一个修改this后的函数。 3.使用场景  call函数的使用多用于类的继承。apply函数可配合Math.max()用于计算数组最大值等。bind函数可用于函数内部有定时器,改变定时器内部的this指向。

欢迎在评论区交流。如果文章对你有所帮助,❤️关注+点赞❤️鼓励一下!博主会持续更新。。。。

往期回顾

 CSS多栏布局-两栏布局和三栏布局

 border边框影响布局解决方案

 css 设置字体渐变色和阴影

css 重置样式表(Normalize.css)

 css实现元素居中的6种方法 

Angular8升级至Angular13遇到的问题

前端vscode必备插件(强烈推荐)

Webpack性能优化

vite构建如何兼容低版本浏览器

前端性能优化9大策略(面试一网打尽)!

vue3.x使用prerender-spa-plugin预渲染达到SEO优化

 vite构建打包性能优化

 vue3.x使用prerender-spa-plugin预渲染达到SEO优化

 ES6实用的技巧和方法有哪些?

 css超出部分显示省略号

vue3使用i18n 实现国际化

vue3中使用prismjs或者highlight.js实现代码高亮

什么是 XSS 攻击?什么是 CSRF?什么是点击劫持?如何防御



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3