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

call 和 apply:改变对象行为的秘密武器(上)

在这里插入图片描述

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6
🍨 阿珊和她的猫_CSDN个人主页
🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》
🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》

文章目录

  • 一、引言
    • 介绍 call 和 apply 的概念
    • 为什么需要 call 和 apply
  • 二、 call 和 apply 的语法和参数
    • call 和 apply 的语法和参数
  • 三、 call 和 apply 的区别
    • 调用方式的区别
    • 参数传递的区别
  • 四、使用 call 和 apply 的场景

一、引言

介绍 call 和 apply 的概念

callapply是JavaScript中的两个方法,它们都可以用来调用函数,并改变函数内部的this指向。

  • call的语法为函数名.call(obj,参数1,参数2,参数3……),它将函数作为一个方法绑定到指定对象上进行调用,并且将函数内部的this设置为指定的对象。

  • apply的语法为函数名.apply(obj,[参数1,参数2,参数3……]),它与call类似,但区别在于它将所有参数写在数组里面。

这两个方法的本质都是通过改变对象的内部指针,将特定函数作为一个方法绑定到指定对象上并进行调用。在某些情况下,函数可能需要在特定的对象上调用,而不是在全局上下文中调用,使用callapply方法可以将函数绑定到特定的对象上,以便在调用时能够正确地访问对象的属性和方法。

为什么需要 call 和 apply

在 JavaScript 中,callapply的作用都是在函数调用时改变函数的执行上下文,也就是函数内部的this。它们的使用场景如下:

  • 在函数作为对象方法的情况下,this会指向对象。如果需要在调用函数时改变this的指向,可以使用callapply方法。
  • 在某些情况下,函数可能需要在特定的对象上调用,而不是在全局上下文中调用。使用callapply方法可以将函数绑定到特定的对象上,以便在调用时能够正确地访问对象的属性和方法。

总之,callapply方法可以帮助我们在函数调用时根据需要改变函数的执行环境,从而实现更加灵活和可定制的代码。

二、 call 和 apply 的语法和参数

call 和 apply 的语法和参数

callapply的语法和参数具体如下:

  • call方法:
    • 语法:call((thisObj(,arg1(, arg2(, (,.argN)))))
    • 说明:
      • 第一个参数是表示要绑定的对象,如果调用时不传参,比如call()call(null)call(undefined),那么this都指向window对象。
      • 传递另一个函数的函数名,那么函数中的this指向这个函数的引用。
      • 传递字符串、数值或布尔类型等基础类型,那么函数中的this指向其对应的包装对象,如StringNumberBoolean
      • 传递一个对象,那么函数中的this指向这个对象。
  • apply方法:
    • 语法:apply((thisObj(,argArray)))
    • 说明:
      • 如果argArray不是一个有效的数组或者不是arguments对象,那么将导致一个TypeError
      • 如果没有提供argArraythisObj任何一个参数,那么Global对象将被用作thisObj,并且无法传递任何参数。

callapply的作用都是在函数调用时改变函数的执行上下文,也就是函数内部的this。它们的使用场景如下:

  • 在函数作为对象方法的情况下,this会指向对象。如果需要在调用函数时改变this的指向,可以使用callapply方法。
  • 在某些情况下,函数可能需要在特定的对象上调用,而不是在全局上下文中调用。使用callapply方法可以将函数绑定到特定的对象上,以便在调用时能够正确地访问对象的属性和方法。

三、 call 和 apply 的区别

调用方式的区别

callapply的主要区别在于调用方式不同:

  • call方法的语法为函数名.call(obj,参数1,参数2,参数3……),其中各个参数用逗号分隔。
  • apply方法的语法为函数名.apply(obj,(参数1,参数2,参数3……)),其中所有参数写在数组中。

尽管callapply的作用相同,但它们的使用方式略有不同。在实际应用中,可以根据具体需求选择使用哪种方法来调用函数。

参数传递的区别

callapply在参数传递方面也存在一些区别:

  • call方法可以传递任意数量的参数,参数之间用逗号分隔。
  • apply方法需要将参数传递给一个数组,数组中的元素就是要传递的参数。

下面是一个示例,展示了如何使用callapply方法以及它们之间的区别:

function sum(num1, num2) {return num1 + num2;
}// 使用 call 方法
var result1 = sum.call(null, 10, 20);
console.log(result1); // 使用 apply 方法
var result2 = sum.apply(null, [10, 20]);
console.log(result2); 

在上述示例中,定义了一个sum函数,它接收两个参数并返回它们的和。通过调用sum.call(null, 10, 20),将null作为this值,并传递了两个参数1020sum函数。通过调用sum.apply(null, [10, 20]),同样将null作为this值,并将一个包含参数1020的数组传递给sum函数。

尽管callapply的作用相同,但它们的使用方式略有不同。在实际应用中,可以根据具体需求选择使用哪种方法来调用函数。

四、使用 call 和 apply 的场景

callapply方法主要用于改变对象的上下文,在以下场景中比较常见:

  1. 改变对象的上下文:可以使用callapply方法将函数作为另一个对象的方法进行调用,从而改变函数内部this的值。
var obj1 = {name: 'John',sayHello: function() {console.log('Hello, ' + this.name);}
};var obj2 = {name: 'Alice'
};obj1.sayHello.call(obj2); 

在上面的示例中,有两个对象obj1obj2obj1有一个名为sayHello的方法。通过使用call方法,将obj2作为this值传递给sayHello方法,输出结果将会是Hello, Alice

  1. 实现继承:可以使用callapply方法来模拟继承。
function Parent() {this.name = 'parent';
}Parent.prototype.sayGoodbye = function() {console.log('Goodbye, ' + this.name);
}function Child() {// 调用父类构造函数,实现属性继承Parent.call(this); this.type = 'child';
}// 子类的原型指向父类的实例,实现方法继承
Child.prototype = Object.create(Parent.prototype); 
// 修复构造函数指向问题,确保子类的构造函数指向自己
Child.prototype.constructor = Child; var child = new Child();
child.sayGoodbye(); 

在上面的示例中,创建了一个父类Parent和一个子类Child。通过使用call方法,在子类的构造函数中调用父类的构造函数,实现属性继承。然后,通过设置子类的原型指向父类的实例,实现方法继承。最后,创建子类的实例,并调用sayGoodbye方法。

除了上述常见场景外,callapply方法还可以用于其他一些情况,例如在某些框架中进行事件绑定、延迟执行等。具体使用场景取决于具体的需求和代码结构。

http://www.lryc.cn/news/261357.html

相关文章:

  • 工作中 docker 的使用积累
  • 初识SpringSecurity
  • 大数据讲课笔记1.4 进程管理
  • 技术点:实现大文件上传
  • 记一次挖矿病毒的溯源
  • day05-报表技术-图形报表
  • 【Spring】@Transactional事务属性详解
  • 通过css3的锚定滚动属性,实现分页加载时让滚动条不闪动
  • 使用Selenium与Scrapy处理动态加载网页内容的解决方法
  • Linux的权限(二)
  • 网络服务IP属地发生变化的原因有哪些?
  • OpenGL 着色器程序的保存和加载(二进制)
  • 【Unity 实用工具篇】| 游戏多语言解决方案,官方插件Localization 实现本地化及多种语言切换
  • 疯狂SQL转换系列- SQL for Tencent Cloud VectorDB
  • Excel中的INDIRECT函数用法
  • Spring-temp
  • 【C++干货铺】会搜索的二叉树(BSTree)
  • 【Spring AOP】 动态代理
  • NAT——网络地址转换
  • Lambda 表达式的常见用法
  • 成本管理常用的ChatGPT通用提示词模板
  • 如何在PHP中处理日期和时间?
  • NO-IOT翻频,什么是翻频,电信为什么翻频
  • 云原生之深入解析OOM和CPU节流
  • 数据结构与算法之递归: LeetCode 93. 复原 IP 地址 (Typescript版)
  • json模块与jsonpath详解
  • ubuntu20.04在noetic下编译orbslam2
  • 64. 最小路径和
  • 惰性加载函数(js的问题)
  • jmeter,读取CSV文件数据的循环控制