apply call bind 简介
Function.prototype.call(thisArg [, arg1, arg2, …])
call() 简述
- call() 方法 调用一个函数, 其具有一个指定的 this 值和分别地提供的参数(参数的列表)。
- 当第一个参数为 null、undefined 的时候, 默认 this 上下文指向window。
call() 简单实例
const name = 'qianyin';
const product = {name: 'linheng',
};function log(...args){console.log(this.name, ...args);
}log(1, 2, 3); // qianyin 1 2 3
log.call(null, 1, 2, 3); // qianyin 1 2 3
log.call(product, 1, 2, 3); // linheng 1 2 3
call() 对箭头函数无效
const name = 'qianyin';
const product = {name: 'linheng',
};const log = (...args) => {console.log(this.name, ...args);
}log(1, 2, 3); // qianyin 1 2 3
log.call(null, 1, 2, 3); // qianyin 1 2 3
log.call(product, 1, 2, 3); // qianyin 1 2 3
补充:
-
箭头函数作为函数的一种形式, 对于this的处理和普通函数有所区别, 其没有自己的 this 上下文,也就是说通过 bind/call/apply 函数方法设置 this 值时无效的,会被忽略;
-
因为箭头函数没有自己的 this 上下文, 所以箭头函数的 this 上下文等于定义函数处的this上下文,也就是最近的一个 this 上下文;
-
你可以认为箭头函数的 this 和调用者无关,只和其定义时所在的 this 上下文相关;
-
如下代码: 在对象 obj 中使用箭头函数定义 log 函数, 那么因为箭头函数没有自己的 this 上下文, 所以 log 函数的 this 上下文等于定义箭头函数处的 this 上下文, 等于 对象 obj 所处的 this 上下文(window)
const name = 'linheng';
const obj = {name: 'qianyin',log: () => {console.log(this.name);}
};
obj.log(); // linheng
- 那么如果我一定要在 obj 中定义一个 log 函数并且使得 this 指向对象 obj 呢?
- 方法一: 使用 function 定义函数
const name = 'linheng';
const obj = {name: 'qianyin',log: function(){console.log(this.name);}
};
obj.log(); // qianyin
- 方法二: 多此一举, 在函数 log 中声明箭头函数并调用, 那么箭头函数的 this 上下文等于定义箭头函数处的 this 上下文, 等于 log 函数的上下文(对象 obj )
const name = 'linheng';
const obj = {name: 'qianyin',log: function(){(() => {console.log(this.name);})();},
};
obj.log(); // qianyin
Function.prototype.apply(thisArg [, Array])
Apply() 简述
- apply() 方法 调用 一个具有给定 this 值的函数,以及作为一个 数组(或类似数组对象) 提供的参数
- call() 方法的作用和 apply() 方法类似,区别就是除第一参数 call() 方法接受的是 参数列表 ,而apply()方法接受的是一个参数 数组(或类数组)。
Apply() 简单实例
const name = 'qianyin';
const product = {name: 'linheng',
};function log(...args){console.log(this.name, ...args);
}log([1, 2, 3]); // qianyin [1 2 3]
log.apply(null, [1, 2, 3]); // qianyin 1 2 3
log.apply(product, [1, 2, 3]); // linheng 1 2 3
Apply() 对箭头函数无效
const name = 'qianyin';
const product = {name: 'linheng',
};const log = (...args) => {console.log(this.name, ...args);
}log([1, 2, 3]); // qianyin [1 2 3]
log.apply(null, [1, 2, 3]); // qianyin 1 2 3
log.apply(product, [1, 2, 3]); // qianyin 1 2 3
Function.prototype.bind(thisArg [, arg1, arg2, …])
bind() 简述
- bind() 方法 创建(拷贝)一个新的函数 , 当这个新函数被调用时 this 指向 thisArg,其 参数列表前几项值 为创建时指定的 参数序列。
- thisArg: 绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用 new 操作符调用绑定函数时,该参数无效。
bind() 绑定 this 上下文
- bind() 最简单的用法是创建一个函数,使这个函数不论怎么调用都有同样的 this 上下文。
- JavaScript 新手经常犯的一个错误是将一个方法从对象中拿出来,然后再调用,却又希望方法中的 this 是原来的对象(比如在回调中传入这个方法)。
- 如果不做特殊处理的话,一般会丢失原来的对象。从原来的函数和原来的对象创建一个绑定函数,则能很漂亮地解决这个问题:
- 如果只是单纯绑定 this 上下文, 完全可以使用箭头函数进行替代
// 例一
this.x = 9;var module = {x: 81,getX: function() { return this.x; }
};
module.getX(); // 返回 81 (通过对象调用函数, 上下文为该对象)
var retrieveX = module.getX; // 获取对象中函数的引用地址
retrieveX(); // 返回 9, 在这种情况下, "this" 指向全局作用域(在全局对象下调用函数)
// 永久为函数 boundGetX 绑定 this 上下文
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81 (函数 this 上下文永久绑定为 module)
// 例二为回调函数绑定 this 上下文
var x = 10;
var obj = {x: 20,get: ffunction(){console.log(this.x);}
};
// 将对象中方法取出(函数的引用地址),作为回调函数, 又因为 setTimeout 回调函数执行的上下文是 window
setTimeout(obj.get, 1000); // 打印 10
// 将对象中方法取出(函数的引用地址),作为回调函数并绑定 this 上下文
setTimeout(obj.get.bind(obj), 1000); // 打印 20
为函数永久绑定固定参数
- bind() 的另一个最简单的用法是使一个函数 拥有预设的初始参数 。
- 这些参数(如果有的话)作为bind()的第二个参数跟在 this(或其他对象)后面。
- 之后它们会 被插入到目标函数的参数列表的开始位置 ,传递给绑定函数的参数会跟在它们的后面。
function list() {return Array.prototype.slice.call(arguments);
}var list1 = list(1, 2, 3); // [1, 2, 3]// 为拷贝 list 方法并绑定初始参数
var leadingThirtysevenList = list.bind(undefined, 37);var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
总结
- 当我们使用一个函数需要改变 this 指向的时候才会用到 call() apply() bind() 当然也别忘记了箭头函数
- call() 和 apply() 是对函数的调用,在调用的同时绑定 this 上下文并传递参数列表
- bind() 是对函数的拷贝进一步的封装, 为函数永久绑定 this 上下文并赋予固定参数
- call() 和 bind() 以参数列表形式给函数指定参数, apply() 则以数组的形式给函数指定参数
apply call bind 的一些运用
类数组转为数组
- 方法一:
const obj = {0: 'q', 1: 'i', 2: 'q', 3: 'a', 4:'n', 5: 'y', 6:'i', 7:'n', length: 8};const arr = [];Array.prototype.push.apply(arr, obj);console.log(arr); // ["q", "i", "q", "a", "n", "y", "i", "n"]
- 方法二:
const obj = {0: 'q', 1: 'i', length: 2};const arr = Array.prototype.slice.call(obj); // [q, i]
为伪数组添加新的元素
- 方法一: 当然你也可以使用 apply
const obj = {0: 'q', length: 1};Array.prototype.push.call(obj, 'i', 'a', 'n');console.log(obj); // {0: 'q', 1: 'i', 2: 'a', 3: 'n'}
- 方法二:
const obj = {0: 'q', length: 1};const push = Array.prototype.push.bind(obj);push('i', 'a', 'n');console.log(obj); // {0: 'q', 1: 'i', 2: 'a', 3: 'n'}
求数组中最大值(最小值一样做法)
const arr = [1,2,3,4,5,6];
const max = Math.max.apply(null, arr);
// 或 const max = Math.max.call(null, ...arr)
console.log(max); // 6
数组合并追加
const arr = [1, 2];
const brr = [3, 4];
Array.prototype.push.apply(arr, brr);
// 或者 Array.prototype.push.call(arr, ...brr);
// 当然还可以这样 arr.push(...brr);
console.log(arr);
使用 log 代理 console.log
function log(...args){// 在可以通过配置, 或者判断当前开发环境来控制是否需要在控制台打印输出if(true){console.log.apply(console, args);}
}
相关文章:

apply call bind 简介
Function.prototype.call(thisArg [, arg1, arg2, …]) call() 简述 call() 方法 调用一个函数, 其具有一个指定的 this 值和分别地提供的参数(参数的列表)。当第一个参数为 null、undefined 的时候, 默认 this 上下文指向window。 call() 简单实例 const name …...

数据结构 单调栈
应用情景 求当前元素 前面/后面,第一个比它 小/大 的元素的 值/下标/下标距离 优点 剔除重复寻路操作,将暴力 O(n^2) 优化到 O(n) 性质 从栈底开始,元素 单调递增/单调递减 单调性视具体情景而定 (找较大值还是较小值、找的方向) 思路…...
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (七):MongoDB的设置
本项目旨在学习如何快速使用 nodejs 开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师) 由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序࿰…...

基于flask和neo4j的医疗知识图谱展示问答系统
如果你仍在为毕业设计的选题发愁,或者想通过技术项目提升专业实力,这个基于Flask和Neo4j的医疗知识图谱展示与问答系统,绝对是个不错的选择! 项目亮点大揭秘: 知识图谱与问答结合:我们采用了医疗场景下的知…...
Python——脚本实现datax全量同步mysql到hive
文章目录 前言一、展示脚本二、使用准备1、安装python环境2、安装EPEL3、安装脚本执行需要的第三方模块 三、脚本使用方法1、配置脚本2、创建.py文件3、执行脚本4、测试生成json文件是否可用 前言 在我们构建离线数仓时或者迁移数据时,通常选用sqoop和datax等工具进…...

Python爬虫教程:从入门到精通
Python爬虫教程:从入门到精通 前言 在信息爆炸的时代,数据是最宝贵的资源之一。Python作为一种简洁而强大的编程语言,因其丰富的库和框架,成为了数据爬取的首选工具。本文将带您深入了解Python爬虫的基本概念、实用技巧以及应用…...

pytorh学习笔记——cifar10(四)用VGG训练
1、新建train.py,执行脚本训练模型: import os import timeimport torch import torch.nn as nn import torchvisionfrom vggNet import VGGbase, VGGNet from load_cifar import train_loader, test_loader import warnings import tensorboardX# 忽略…...

CRLF、UTF-8这些编辑器右下角的选项的意思
经常使用编辑器的小伙伴应该经常能看到右下角会有这么两个选项,下图是VScode中的示例,那么这两个到底是啥作用呢? 目录 字符编码ASCII 字符集GBK 字符集Unicode 字符集UTF-8 编码 换行 字符编码 此部分参考博文 在计算机中,所有…...

【C++干货篇】——类和对象的魅力(四)
【C干货篇】——类和对象的魅力(四) 1.取地址运算符的重载 1.1const 成员函数 将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后面。const实际修饰该成员函数隐含的this指针(this指向的对…...

基于java的诊所管理系统源码,SaaS门诊信息系统,二次开发的不二选择
门诊管理系统源码,诊所系统源码,saas服务模式 医疗信息化的新时代已经到来,诊所管理系统作为诊所管理和运营的核心工具,不仅提升了医疗服务的质量和效率,也为患者提供了更加便捷和舒适的就医体验,同时还推动…...
O2OA如何实现文件跨服务器的备份
O2OA可以外接存储服务器,但是一个存储服务器上怕磁盘损坏等问题导致文件丢失,所以需要实现文件跨服务器备份。 整体过程: 1、SSH免密登录配置 2、增加一个同步推送文件的.sh文件 3、编辑crontab 增加定时任务执行上一步的.sh文件 一、配…...

语音提示器-WT3000A离在线TTS方案-打破语种限制/AI对话多功能支持
前言: TTS(Text To Speech )技术作为智能语音领域的重要组成部分,能够将文本信息转化为逼真的语音输出,为各类硬件设备提供便捷的语音提示服务。本方案正是基于唯创知音的离在线TTS(离线本地音乐播放与在线…...
使用HAL库的STM32工程,实现DMA传输USART发送接收数据
以串口3为例,初始化部分为STM32CubeMX生成代码 串口初始化 UART_HandleTypeDef huart3; DMA_HandleTypeDef hdma_usart3_rx; DMA_HandleTypeDef hdma_usart3_tx;/* USART3 init function */ void MX_USART3_UART_Init(void) {/* USER CODE BEGIN USART3_Init 0 */…...

常用排序算法总结
内容目录 1. 选择类排序 1.1 直接选择排序1.2 堆排序 2. 交换类排序 2.1 冒泡排序2.2 快速排序 3. 插入类排序 3.1 直接插入排序3.2 希尔排序 4. 其它排序 4.1 归并排序4.2 基数排序/桶排序 排序 1. 选择类排序 选择类排序的特征是每次从待排序集合中选择出一个最大值或者最…...

[项目详解][boost搜索引擎#2] 建立index | 安装分词工具cppjieba | 实现倒排索引
目录 编写建立索引的模块 Index 1. 设计节点 2.基本结构 3.(难点) 构建索引 1. 构建正排索引(BuildForwardIndex) 2.❗构建倒排索引 3.1 cppjieba分词工具的安装和使用 3.2 引入cppjieba到项目中 倒排索引代码 本篇文章,我们将继续项…...
R语言编程
一、R语言在机器学习中的优势 R语言是一种广泛用于统计分析和数据可视化的编程语言,在机器学习领域也有诸多优势。 丰富的包:R拥有大量专门用于机器学习的包。例如,caret包是一个功能强大的机器学习工具包,它提供了统一的接口来训练和评估多种机器学习模型,如线性回归、决…...

Mysql主主互备配置
在现有运行的mysql环境下,修改相关配置项,完成主主互备模式的部署。 下面的配置说明中设置的mysql互备对应服务器IP为: 192.168.1.6 192.168.1.7 先检查UUID 在mysql的数据目录下,检查主备mysql的uuid(如下的server-…...
如何预防数据打架?数据仓库如何保持指标数据一致性开发指南(持续更新)
大数据开发人员最经常遇到尴尬和麻烦的事是,指标开发好了,以为万事大吉了。被业务和运营发现这个指标在不同地方数据打架,显示不同的数值。为了保证指标数据一致性,要从整个开发流程做好。 目录 一、数据仓库架构规划 二、数据抽取与转换 三、数据存储管理 四、指标管…...

我谈Canny算子
在Canny算子的论文中,提出了好的边缘检测算子应满足三点:①检测错误率低——尽可能多地查找出图像中的实际边缘,边缘的误检率(将边缘识别为非边缘)低,且避免噪声产生虚假边缘(将非边缘识别为边缘…...

算法的学习笔记—平衡二叉树(牛客JZ79)
😀前言 在数据结构中,二叉树是一种重要的树形结构。平衡二叉树是一种特殊的二叉树,其特性是任何节点的左右子树高度差的绝对值不超过1。本文将介绍如何判断一棵给定的二叉树是否为平衡二叉树,重点关注算法的时间复杂度和空间复杂度…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...