当前位置: 首页 > news >正文

apply、call和bind的作用和区别

apply与call

首先介绍一下apply与call,因为这两个方法的功能和使用方式都差不多,只是传参的方式不同。call和apply的作用都是改变函数运行时的上下文(context)

语法

fun.call(thisArg, arg1, arg2, ...)fun.apply(thisArg, argsArray)

参数

thisArg:在fun函数运行时this的指向
arg1, arg2, ...:传递给函数的参数列表
argsArray:一个数组或类数组对象,数组中的元素将被作为参数传递给函数。

示例

function fun(name, age) {console.log(name, age);}fun('张三', 18);fun.apply(this, ['张三', 18]);fun.call(this, '张三', 18);

将会输出同样的结果:

改变指向

window.name = 'windowName';const user = {name: 'userName',};function fun() {console.log(this.name);}fun(); //  Cannot read properties of undefined (reading 'name')fun.apply(window); // windowNamefun.apply(user); // userName

判断元素类型

直接使用typeof进行类型判断时,并不能识别出Array和null,都会识别为object,因此需要使用Object.prototype.toString()方法

Object.prototype.toString.apply([1, 2]) // Array
Object.prototype.toString.call([1, 2]) // ArrayObject.prototype.toString.apply({}) // Object
Object.prototype.toString.call({}) // Object

注意:元素本身的toString()并不能打印出类型,只会输出元素的值

bind

bind与call和apply相似,但它不会立即执行函数,而是返回一个新的函数,这个新函数的this被永久绑定到第一个参数提供的值。

const user = {name: 'userName',};function fun() {console.log(this.name);}const res = fun.bind(user);res(); // userName

总结

call方法

优势:

  1. 立即执行:call方法会立即调用函数,并允许你指定函数运行时的this值。
  2. 参数列表:可以传递任意数量的参数,只需在this值之后依次列出即可。

区别:call通过参数列表传递给函数,而不是数组。

apply方法

优势:

  1. 立即执行:与call一样,apply也会立即调用函数,并允许你指定函数运行时的this值。
  2. 数组或类数组参数apply可以接受一个数组(或类数组对象)作为参数,这使得当你需要传递大量参数时,applycall更方便。

区别:apply只接受两个参数,第二个参数必须是一个数组或类数组对象。

bind方法

优势:

  1. 不立即执行bind方法不会立即调用函数,而是返回一个新的函数,这个新函数的this被永久绑定到提供的值。
  2. 预设参数:可以在绑定this的同时预设一些参数,使得新函数在调用时可以接收更多参数。

区别:

      1. 执行时机bind不会立即执行函数,而是返回一个新的函数实例。

      2. 多次调用:由于bind返回的是一个新函数,你可以多次调用这个新函数,而callapply在调用后即执行完毕。

综合比较

  • 执行时机

    • callapply:立即执行函数。
    • bind:返回一个新的函数,可以在任何需要的时候调用。
  • 参数传递

    • call:直接传递参数列表。
    • apply:传递一个包含所有参数的数组或类数组对象。
    • bind:可以在绑定this的同时预设参数,并在调用时接收更多参数。
  • 使用场景

    • 需要立即调用一个函数并指定this值时,使用callapply
    • 需要创建一个新函数,以便在任何时候调用并预设this值和参数时,使用bind

总的来说,callapply在功能上非常相似,主要区别在于参数传递的方式。而bind则提供了更大的灵活性,它允许创建一个新的函数实例,可以延迟执行并预设参数。


http://www.mrgr.cn/news/34330.html

相关文章:

  • 装饰器模式
  • Vue使用Vue Router路由:开发单页应用
  • 【网络协议栈】传输层的意义 和 UDP协议结构的解析(内含逻辑图解通俗易懂)
  • yolo自动化项目实例解析(四)ui页面整理1 (1.85)
  • kafka负载均衡迁移(通过kafka eagle)
  • 独立站崛起:2024全球商家共谋增长新蓝图
  • Kibana中突然看不到日志ElasticSearch突然采集不到日志问题解决分析
  • Linux——虚拟机和Windows间的文件传输方式
  • 【运维监控】influxdb 2.0 + grafana 11 监控jmeter 5.6.3 性能指标(1)
  • 9.23-部署项目
  • 基于深度学习的竞争性对抗学习
  • 场景题面试题——第一篇
  • freemobus阅读笔记
  • 比亚迪技术面试(测试、测开)
  • 公测两次延期、被网易拉黑,乙游《米修斯之印》能“活”下来吗?
  • python对文件的写入和追加
  • 基于QT的C++中小项目软件开发架构源码
  • 【Centos 8安装VNC及多用户配置详细教程】
  • docker安装及使用
  • 公司将被千万美金收购,工程师却误删数据库 —— 没 有 备 份!!!