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

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);}
}

image

相关文章:

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,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师) 由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序&#xff0…...

基于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。本文将介绍如何判断一棵给定的二叉树是否为平衡二叉树,重点关注算法的时间复杂度和空间复杂度…...

SSM学习day01 JS基础语法

一、JS基础语法 跟java有点像,但是不用注明数据类型 使用var去声明变量 特点1:var关键字声明变量,是为全局变量,作用域很大。在一个代码块中定义的变量,在其他代码块里也能使用 特点2:可以重复定义&#…...

kubeadm快速自动化部署k8s集群

目录 一、准备环境 二、安装docker--三台机器都操作 三、使用kubeadm部署Kubernetes 在所有节点安装kubeadm和kubelet、kubectl 配置启动kubelet(所有主机) master节点初始化 Mater重新完成初始化 执行Master初始化后的提示配置 配置使用网络插件 创建flannel网络 …...

解决JAVA使用@JsonProperty序列化出现字段重复问题(大写开头的字段重复序列化)

文章目录 引言I 解决方案方案1:使用JsonAutoDetect注解方案2:手动编写get方法,JsonProperty注解加到方法上。方案3:首字母改成小写的II 知识扩展:对象默认是怎样被序列化?引言 需求: JSON序列化时,使用@JsonProperty注解,将字段名序列化为首字母大写,兼容前端和第三方…...

分布式理论基础

文章目录 1、理论基础2、CAP定理1_一致性2_可用性3_分区容错性4_总结 3、BASE理论1_Basically Available(基本可用)2_Soft State(软状态)3_Eventually Consistent(最终一致性)4_总结 1、理论基础 在计算机…...

Java应用程序的测试覆盖率之设计与实现(二)-- jacoco agent

说在前面的话 要想获得测试覆盖率报告,第一步要做的是,采集覆盖率数据,并输入到tcp。 而本文便是介绍一种java应用程序部署下的推荐方式。 作为一种通用方案,首先不想对应用程序有所侵入,其次运维和管理方便。 正好,jacoco agent就是类似于pinpoint agent一样,都使用…...

【机器学习】13. 决策树

决策树的构造 策略:从上往下学习通过recursive divide-and-conquer process(递归分治过程) 首先选择最好的变量作为根节点,给每一个可能的变量值创造分支。然后将样本放进子集之中,从每个分支的节点拓展一个。最后&a…...

《a16z : 2024 年加密货币现状报告》解析

加密社 原文链接:State of Crypto 2024 - a16z crypto译者:AI翻译官,校对:翻译小组 当我们两年前第一次发布年度加密状态报告的时候,情况跟现在很不一样。那时候,加密货币还没成为政策制定者关心的大事。 比…...

Laravel 使用Simple QrCode 生成PNG遇到问题

最近因项目需求,需要对qrcode 进行一些简单修改,发现一些问题,顺便记录一下 目前最新的版本是4.2,在环境是 PHP8 ,laravel11 的版本默认下载基本是4.0以上的 如下列代码 QrCode::format(png)->generate(test);这样…...

一站式学习 Shell 脚本语法与编程技巧,踏出自动化的第一步

文章目录 1. 初识 Shell 解释器1.1 Shell 类型1.2 Shell 的父子关系 2. 编写第一个 Shell 脚本3. Shell 脚本语法3.1 脚本格式3.2 注释3.2.1 单行注释3.2.2 多行注释 3.3 Shell 变量3.3.1 系统预定义变量(环境变量)printenv 查看所有环境变量set 查看所有…...

批处理操作的优化

原来的代码 Override Transactional(rollbackFor Exception.class) public void batchAddQuestionsToBank(List<Long> questionIdList, Long questionBankId, User loginUser) {// 参数校验ThrowUtils.throwIf(CollUtil.isEmpty(questionIdList), ErrorCode.PARAMS_ERR…...

wordpress建站网页无法运/seo优化网站技术排名百度推广

本文主要向大家介绍了Oracle数据库之Oracle分组函数以及数据分组&#xff0c;通过具体的内容向大家展现&#xff0c;希望对大家学习Oracle数据库有所帮助。一、分组函数1、sum()求和函数、max()求最大值函数、min()求最小值函数、avg()求平均值函数、count()求总行数函数Expres…...

wordpress百度云/seo软件简单易排名稳定

Best Financing Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 29 Accepted Submission(s): 3 Problem Description小A想通过合理投资银行理财产品达到收益最大化。已知小A在未来一段时间中的收入情况&#…...

深圳市企业服务体系平台建设方案/全网优化哪家好

以下介绍经常使用的集合类&#xff0c;这里不介绍集合类的使用方法&#xff0c;只介绍每个集合类的用途和特点&#xff0c;然后通过比较相关集合类的不同特点来让我们更深入的了解它们。Collection接口Collection是最基本的集合接口&#xff0c;一个Collection代表一组Object&a…...

建设雅马哈官方网站/全自动引流推广软件

今天给大家分享一个轻量级Vue.js全屏滚动进度条组件VueScrollProgress。vue-scroll-progress 一款基于vue.js构建的页面滚动进度条组件&#xff0c;非常小巧&#xff0c;GZIP压缩后不到1KB。安装$ npm i vue-scroll-progress -S也支持通过CDN引入使用。引入组件// 在main.js中引…...

唐山设计网站公司/沈阳关键词优化费用

转载请注明出处&#xff1a; http://www.cnblogs.com/darkknightzh/p/5797526.html 参考网址&#xff1a; http://caffe.berkeleyvision.org/installation.html#prerequisites 1. 必须的依赖&#xff1a;Boost > 1.55&#xff0c;CUDA&#xff0c;BLAS 看一下自己的CUDA安装…...

怎么做动态的实时更新的网站/免费平台

1. 基本语法test condition或[ condition ]使用括号方式时&#xff0c;条件与括号之间要加空格。2. 测试文件状态例&#xff1a;测试文件 scores.txe 是否可执行。 [rootlocalhost ~]# [ -x scores.txt ] [rootlocalhost ~]# echo $? 1 条件测试可以使用以下条件表达…...