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

你真的弄懂this指向了吗

前言

在说 this 指向之前,请观察以下代码,并说出它们的输出结果:

第 1 组:标准函数

window.color = "red";
let o = {color: "blue",
};
function sayColor() {console.log(this.color);
}sayColor(); // 输出值是什么?o.sayColor = sayColor;
o.sayColor(); // 输出值是什么?

第 2 组:箭头函数

window.color = "red";
let o = {color: "blue",
};
let sayColor = () => console.log(this.color);sayColor(); // 输出值是什么?o.sayColor = sayColor;
o.sayColor(); // 输出值是什么?

一、标准函数和箭头函数的 this 指向

先公布一下以上函数的输出结果,不知道屏幕前的你答对了吗?

第 1 组输出结果如下

sayColor(); // 'red'
o.sayColor(); // 'blue'

第 2 组输出结果如下

sayColor(); // 'red'
o.sayColor(); // 'red'

为什么会呈现出这样的输出结果呢?

标准函数中,this 指向的是把函数当成方法调用的上下文对象,在网页的全局上下文中调用函数时,this 指向 window,因此 this 指向是会发生改变的

箭头函数中,this 指向的是定义箭头函数的上下文对象,箭头函数在哪个对象的上下文中定义的,this 就指向谁,,箭头函数中,this 的指向是固定的

二、改变 this 指向

我们知道,函数其实是一个对象,因此它有属性和方法。每个函数都有两个属性:lengthprototype。其中 length 属性保存函数定义的命名参数的个数,prototype 属性保存引用类型所有实例和方法。callapplybind ,就是保存在 prototype 中的方法。

前面已经提到,标准函数箭头函数的默认 this 指向,但是在某些时候,我们需要改变 this默认指向,这时候我们就需要用到 callapplybind 方法,这 3 个方法都可以用来改变 this 指向,接下来我们来详细介绍这 3 个方法。

1. call

call() 方法会以指定的 this 值来调用函数,即会设置调用函数时函数体内 this 对象的值。 call() 方法接收两个参数,第 1 个参数是函数内的 this 值,第 2 个参数是调用该函数需要传入的值。第 1 个参数是必填项,第 2 个参数可以不填。

call(this, num);

以前言中的代码举例,观察 this 的变化

window.color = "red";
let o = {color: "blue",
};function sayColor() {console.log(this.color);
}sayColor(); // 'red'sayColor.call(o); // 'blue'

sayColor 是一个标准函数,它的 this 指向是调用时的上下文对象,我们是在全局调用的,因此它的上下文对象应该是 window,所以 sayColor() 输出 'red' 是毫无疑问的。但是 sayColor.call(o) 为什么会输出 'blue' 呢?虽然它也是在全局上下文中调用的,但是我们利用 call() 方法,给它指定了一个新的 this 值,也就是对象 o,所以这里的 this.color 指的是对象 o 中的 color

call() 方法传值需要将参数一个一个列出来,用 ',' 分开,从第 2 个参数开始,看下面示例:

function sum(num1, num2) {return num1 + num2;
}
num.call(this, 10, 20); // 30

2. apply

apply() 方法和 call() 作用一样,第一个参数也是指定 this 值,但是参数需要是 Array 实例或者 arguments 对象,看下面示例:

function sum(num1, num2) {return num1 + num2;
}function callSum1(num1, num2) {                 return sum.apply(this, arguments);
}function callSum2(num1, num2) {return sum.apply(this, [num1, num2]);
}console.log(callSum1(10, 20)); // 30
console.log(callSum2(10, 20)); // 30

从示例中可以看出,无论是传入类数组对象还是数组,可以进行正常的传值。call()apply() 真正强大的地方在于,它们可以控制函数调用上下文,可以将任意对象设置为任意函数的作用域。

3. bind

call()apply() 不同,bind() 方法会新创建一个函数实例,这个新函数的 this 值,会绑定到传给 bind() 的对象。下面来看示例:

window.color = "red";
let o = {color: "blue",
};function sayColor() {console.log(this.color);
}
let objectSayColor = sayColor.bind(o);objectSayColor(); // 'blue'

在这里,我们在 sayColor() 上调用了 bind() 方法,并传入了一个对象 o ,创建了一个新的函数 objectSayColor(),指定其作用域为对象 o。所以,我们在任意地方调用该函数,输出的都是字符串 'blue'

4. 三者之间的区别

通过以上的分析,我们已经知道,call()apply()bind() 都可以用来修改 this 指向。它们的区别如下:

  • call()apply() 是直接修改原函数的 this 值,不会创建新的函数
  • call() 传值需要将值一个一个列出来,用 ',' 隔开
  • apply() 只能传入数组格式或者类数组格式的值
  • bind() 会返回一个修改过 this 值 的新函数

三、总结

call() 、apply() 、bind() 是为了灵活改变函数 this 指向而发明的,他们的主要用途也是用来改变 this 指向。当然,由于这些方法本身的特性,也可以用来做些其它的事情,比如计算数组最大值、最小值等。
不过,这个用途并不广泛,因为解构赋值可以更轻松达到这个目的。

const arr = [1, 2, 3, 4, 5];Math.max.apply(this, arr);
Math.min.apply(this, arr);Math.max(...arr);
Math.min(...arr);

相关文章:

你真的弄懂this指向了吗

前言 在说 this 指向之前,请观察以下代码,并说出它们的输出结果: 第 1 组:标准函数 window.color "red"; let o {color: "blue", }; function sayColor() {console.log(this.color); }sayColor(); // 输…...

阿里云服务器使用教程:使用xshell、xFtp工具连接阿里云服务器(Centos7)并修改Centos7的yum源为阿里镜像源

目录 1、下载并安装xshell、xFtp 2、远程连接阿里云服务器 3、 修改Centos7的yum源为阿里镜像源 1、下载并安装xshell、xFtp XShell可以在Windows界面下来访问远端不同系统下的服务器,从而比较好的达到远程控制终端的目的。它支持 RLOGIN、SFTP、SERIAL、TELNET、…...

一文快速入门 HTML 网页基础

专栏简介: 前端从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录 1.HTML 结构 1.1. 认识 HTML 标签 1.2 HTML 文件结构…...

DEJA_VU3D - Cesium功能集 之 100-任意多边形(标绘)

前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,所以暂时打算一周2-3更的样子来更新本专栏(每篇博文都会奉上完整demo的源代码,…...

Cadence OrCAD Capture全局修改原理图的非本地库符号的方法图文教程Repalce Catch功能

⏪《上一篇》   🏡《总目录》   ⏩《下一篇》 目录 1,概述2,修改方法2.1,新建本地库2.2,待修改搬入本地库2.3,修改原理图符号2.4,全局更新原理图符号3,总结B站关注“硬小二”浏览更多演示视频 1,概述 在完成原理图设计...

npm包版本号详解

npm包在发布时,需要按照包版本语义化中的约定去更新设置,例如我们常见的1.0.0,1.0.1,0.0.1等这样的版本号,那么这些数字分别代表什么意思呢?下面我们将详细介绍。 npm版本号的组成 一个完整的版本号&…...

ubuntu 系统安装docker——使用docker打包python项目,整个流程介绍

目录 1 安装docker和配置镜像源 2 下载基础镜像 3 通过镜像创建容器 4 制作项目所需的容器 5 容器制作好后打包为镜像 6 镜像备份为.tar文件 7 从其他服务器上恢复镜像 8 docker的其他常用指令 首先科普一下镜像、容器和实例; 镜像:相当于安装包&…...

MySQL事务篇

MySQL事务篇 一、一条Insert语句 为了故事的顺利发展,我们需要创建一个表: CREATE TABLE t (id INT PRIMARY KEY,c VARCHAR(100) ) EngineInnoDB CHARSETutf8;然后向这个表里插入一条数据: INSERT INTO t VALUES(1, 刘备); 现在表里的数据就…...

【Redis】搭建分片集群

目录 集群结构 准备实例和配置 启动 创建集群 测试 集群结构 分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个 master包含一个slave节点,结构如下: 这里我们会在同一台虚…...

RoCEv2网络部署实践

延续上篇RoCE网络的介绍,我们知道承载ROCEv2流量必须有一张无损网络。 本章主要介绍在以太网环境部署无损网络的关键点。 首先是QoS,包含流分类和队列调度两部分。 流分类:在网络接入设备(TOR)配置if-match类的语句&am…...

【HashMap】| 深度剥析Java SE 源码合集Ⅱ | 你会吗?

目录一. 🦁 HashMap介绍1.1 特点1.2 底层实现二. 🦁 结构以及对应方法分析2.1 结构组成2.1.1 成员变量2.1.2 存储元素的节点类型2.1.2.1 链表Node类2.1.2.2 树节点类2.1.2.3 继承关系2.2 方法实现2.2.1 HashMap的数组初始化2.2.2 计算hash值2.2.3 添加元…...

剑指 Offer 39. 数组中出现次数超过一半的数字

剑指 Offer 39. 数组中出现次数超过一半的数字 难度:easy\color{Green}{easy}easy 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: …...

使用python控制摄像头

前言 当今,随着计算机技术的发展,摄像头已经成为了人们生活中不可或缺的一部分。而Python作为一种流行的编程语言,也可以轻松地控制和操作摄像头。无论你是想用Python写一个简单的摄像头应用程序,还是想在机器学习和计算机视觉项…...

Linux文件系统

目录 1、常见的linux文件系统 2、文件系统的组成 inode的内容: 可以用stat命令,查看某个文件的inode信息 inode的大小 inode号码 使用 ls -i来查看文件的inode号码 使用 df -i命令,查看每个硬盘分区的inode总数和已经使用的数量&#xff…...

扬帆优配|引活水 增活力 促转型 创业板助力实体经济高质量发展

立异就是生产力,企业赖之以强,国家赖之以盛。全面注册制变革持续开释立异生机。日前,创业板公司已开端连续公布2022年度年度报告和2023年第一季度成绩预告,从频频传来的“喜报”中可窥见立异驱动开展战略下新兴工业的强劲开展态势…...

【c++】:STL模板中string的使用

文章目录 STL简介一.认识string二.string中基本功能的使用总结STL简介 STL(standard template libaray-标准模板库):是C标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。STL的版本 原始版本 Alexand…...

华为OD机试用Python实现 -【连续字母长度 or 求第 K 长的字符串长度】 | 2023.Q1 A卷

华为OD机试题 本篇题目:连续字母长度 or 求第 K 长的字符串长度题目输入描述输出描述示例一输入输出说明示例二输入输出说明示例三输入输出说明Code代码编写逻辑最近更新的博客 华为od 2023 | 什么是华为od,od...

前端处理并发的最佳实践

什么是并发? 因为js是单线程的,所以前端的并发指的是在极短时间内发送多个数据请求,比如说循环中发送ajax。 举一个简单的例子: 下面一段代码是常规的mount阶段执行的请求: useEffect(async () > {console.time…...

【SOP 】配电网故障重构方法研究【IEEE33节点】(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

[MySQL索引]4.索引的底层原理(三)

索引的底层原理(三)哈希索引InnoDB自适应哈希索引哈希索引 memory存储引擎支持的是哈希索引,memory是支持内存的存储引擎。 哈希表中的元素没有任何顺序可言,只能进行等值比较,包括范围搜索、前缀搜索like、order by…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...

C# WPF 左右布局实现学习笔记(1)

开发流程视频: https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源码: GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF应用(.NET Framework) 2.…...

Linux——TCP和UDP

一、TCP协议 1.特点 TCP提供的是面向连接、可靠的、字节流服务。 2.编程流程 (1)服务器端的编程流程 ①socket() 方法创建套接字 ②bind()方法指定套接字使用的IP地址和端口。 ③listen()方法用来创建监听队列。 ④accept()方法处理客户端的连接…...

Ubantu-Docker配置最新镜像源250605

尝试其他镜像加速器 阿里云镜像加速器:登录阿里云,进入容器镜像服务获取专属加速器地址。毫秒镜像:https://docker.1ms.run。DockerHub镜像加速器:https://docker.xuanyuan.me。Docker Hub 镜像加速服务:https://dock…...

浅谈未来汽车电子电气架构发展趋势中的通信部分

目录 一、引入 1.1市场占比演化 1.2未来发展趋势 二、纯电动汽车与传统汽车的区别 2.1 纯电车和燃油车的架构(干货) 2.2 新能源汽车的分类 ⚡ 1. 纯电动汽车(BEV) 🔋 2. 插电式混合动力(PHEV&#…...