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

重走前端路JS进阶篇:This 指向与箭头函数

JavaScript 高级

This 指向规则

案例

    function foo() {console.log(this)}// 1 调用方式1foo();// 2 调用方式2 放入对象中调用var obj = {name: "why",foo: foo}obj.foo()// 调用方式三 通过 call/apply 调用foo.call("abc")

image-20230223171236633

指向定义

this 是js 给函数的一个绑定值。

  1. 函数在调用时 JavaScript会默认给this绑定一个值;
  2. this的绑定和定义的位置(编写的位置)没有关系;
  3. this的绑定和调用方式以及调用的位置有关系
  4. this是在运行时被绑定的

无严格模式下 为 window 如果打开严格模式 则为 udnefined

this 的绑定规则如下:

  1. 绑定一:默认绑定 PS: 没有绑定到任何对象时 & 函数定义在对象中但是被独立调用 对象也是 window

  2. 绑定二:隐式绑定 PS:由JS 绑定到调用对象 指向对象

  3. 绑定三:new绑定

    • new 执行过程
    • 1 创建空对象
    • 2 修改this 指向为空对象
    • 3 执行函数体代码
    • 没有显示返回非空对象时 默认返回这个对象
  4. 绑定四 显示绑定

    • 如果我们不希望在 对象内部 包含这个函数的引用,同时又希望在这个对象上进行强制调用

    • function foo() {console.log(this)
      }   
      var obj = {name: "why",foo: foo}
      foo.call(123)console 输出内容 {name: 'why', foo: ƒ}
      
    • call/apply 可以帮助我们完成这个效果

额外函数补充

Call / Apply 调用方法 两者区别不大 但是又细微差别

apply

    function foo(name, age, height) {console.log("foo 函数this 指向", this);console.log("参数:", name, age, height);}// 普通调用  直接入参foo("why", 18, 1.22)// apply// 第一个参数 绑定 this // 第二个参数 传入额外的实参 以数组的形式//   foo.apply("apply",["why", 18, 1.22])foo.apply("123", ["why", 18, 1.22])

call

    function foo(name, age, height) {console.log("foo 函数this 指向", this);console.log("参数:", name, age, height);}// call// 第一个参数 绑定 this// 后续参数以 参数列表形式 foo.call("call", "远目鸟", 18, 12)

两者 相同处 都是调用方法 第一参数都指向this 唯一区别只在后续传入的参数的形势

  • apply 为数组
  • call 为列表 以 , 分割

bind :会创建 绑定函数 我们希望调用foo 的时候总是让this 指向 obj

    function foo() {console.log("foo 函数this 指向", this);}var obj = {name: "why"}// 需求 调用foo时 总是绑定 obj var bar = foo.bind(obj)bar()

在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。 实际开发中 使用不多 作为参考 了解即可

内置函数

一般 对于浏览器 的内置函数 或者是第三方框架的 this 指向 我们只能用经验去判断 一个一个去源码或者文档查看和并不现实

This 优先级

  1. 默认绑定 优先级最低
  2. 显式绑定 高于隐式绑定
  3. new 高于隐式绑定 PS:new不能和 call/apply 一起使用
  4. new绑定优先级高于bind
  5. 同显式 bind 优先级高于 call/apply

拓展: 规则之外

**情况一:**如果在显示绑定中,我们传入一个null或者undefined,那么这个显示绑定会被忽略,使用默认规则:

    function foo() {console.log("foo 函数this 指向", this);}var obj = {name: "why"}foo.call(obj)foo.call(null)foo.call(undefined)var bar = foo.bind(obj)bar()

但是打开严格模式 就会可以使用基础属性 直接显示 null 或者 undefined

**情况二:**创建一个函数的 间接引用,这种情况使用默认绑定规则。

  • 这种情况 (obj2.foo = obj1.foo) 会使用默认规则 指向 window
    var obj1 = {name: "obj1",foo: function () {console.log("foo 函数this 指向", this);}}var obj2 = {name: "obj2"};obj1.foo();(obj2.foo = obj1.foo)();

**情况三:**箭头函数

  • 箭头函数不会绑定this、arguments属性
  • 箭头函数不能作为构造函数来使用
    // {} 是执行体var arrFn = () => { }// 指向的是对象 需要加小括号才可以做到var arrFn = () => ({ name: "why" })

箭头函数

  • 基本写法

    • ():函数的参数

    • {}:函数的执行体

    •     var foo3 = (name, age) => {console.log("箭头函数的函数体")console.log(name, age)}
      
  • 优化写法

    • 只有一个参数时, 可以省略()

          names.forEach(item => {console.log(item)})
      
    • 只有一行代码时, 可以省略{}

      names.forEach(item => console.log(item))
      
    • 只要一行代码时, 表达式的返回值会作为箭头函数默认返回值, 所以可以省略return

      var newNums = nums.filter(item => item % 2 === 0)
      var newNums = nums.filter(item => item % 2 === 0)
      
    • 如果箭头函数默认返回的是对象, 在省略{}的时候, 对象必须使用()包裹 () => ({name: “why”})

          var arrFn = () => ["abc", "cba"]var arrFn = () => {} // 注意: 这里是{}执行体var arrFn = () => ({ name: "why" })console.log(arrFn())
      

箭头函数不使用this的四种标准规则(也就是不绑定this),而是根据外层作用域来决定this。

我们来看一个模拟网络请求的案例:

  • 这里我使用setTimeout来模拟网络请求,请求到数据后如何可以存放到data中呢?
  • 我们需要拿到obj对象,设置data;
  • 但是直接拿到的this是window,我们需要在外层定义:var _this = this
  • _在setTimeout的回调函数中使用_this就代表了obj对象
  • 但是如果使用箭头函数根据特性他会向上寻找this 省去了_this = this的操作
    var obj = {data: [],getData: function () {request("/11", (res) => {this.data = [].concat(res)})}}function request(url, callbackFn) {var res = ["abc", "cba", "nba"]callbackFn(res)}obj.getData()

总结

  1. this的指向问题与优先级 是踏入JS的敲门砖,如果不先系统了解之后使用的时候可能会出现奇怪的错误
  2. 使用ES6的语法 箭头函数 提前熟悉ES6语法可以提升开发效率

相关文章:

重走前端路JS进阶篇:This 指向与箭头函数

JavaScript 高级 This 指向规则 案例 function foo() {console.log(this)}// 1 调用方式1foo();// 2 调用方式2 放入对象中调用var obj {name: "why",foo: foo}obj.foo()// 调用方式三 通过 call/apply 调用foo.call("abc")指向定义 this 是js 给函数的…...

Python基础:函数式编程

一、概述 Python是一门多范式的编程语言,它同时支持过程式、面向对象和函数式的编程范式。因此,在Python中提供了很多符合 函数式编程 风格的特性和工具。 二、lambda表达式(匿名函数) 除了 函数 中介绍的 def语句,P…...

【YBT2023寒假Day14 C】字符串题(SAM)(树链剖分)(线段树)

字符串题 题目链接:YBT2023寒假Day14 C 题目大意 对于一个字符串 S 定义 F(S) 是 fail 树上除了 0 点其它点的深度和。 G(S) 是 S 每个子串 S’ 的 F(S’) 之和。 然后一个空串,每次在后面加一个字符,要你维护这个串的 G 值。 思路 考虑…...

Tailwind CSS 在Vue中的使用

什么是Tailwind CSS? Tailwind CSS 是一个功能类优先的 CSS 框架,它集成了诸如 flex, pt-4, text-center 和 rotate-90 这样的的类,支持 hover 和 focus 样式,它们能直接在脚本标记语言中组合起来,构建出任何设计。 …...

三层楼100人办公网络如何规划设计实施(实战案例)

如何设计组网 1.采用防火墙+三层交换机+二层POE交换机+AP的方案 2.三层交换机作为网络的核心,提供网络的配置、划分和各个VLAN间的数据交换,而每个VLAN由二层交换机组建 3.网络主干设备的选型,建议网络主干设备或核心层设备选择具备第3层交换功能的高性能主干交换机。 4…...

Redis:实现全局唯一ID

Redis:实现全局唯一ID一. 概述二. 实现(1)获取初始时间戳(2)生成全局ID三. 测试为什么可以实现全局唯一?其他唯一ID策略补充:countDownLatch一. 概述 全局ID生成器:是一种在【分布式…...

webpack打包基本原理——实现webpack打包核心功能

webpack打包的基本原理 核心功能就是把我们写的模块化代码转换成浏览器能够识别运行的代码,话不多说我们一起来了解它 首先我们建一个空项目用 npm init -y 创建一个初始化的,在跟目录下创建src文件夹,src下创建index.js,add.js…...

git的使用(终端输入指令) 上

git目录前言1.创建仓库2.创建文件和修改数据状态分区![分区](https://img-blog.csdnimg.cn/d124dec6b2b14769ad20b75490f29cae.png)3 .删除、撤销重置 、和比较前言 今天带大家手把手敲一遍 git 流程: 安装一下git(详细观看我之前发的git文档&#xff0…...

react定义css样式,使用less,css模块化

引入外部 css文件 import ./index.css此时引入的样式是全局样式 使用less 安装 npm i style-loader css-loader sass-loader node-sass -D生成config文件夹 npm run eject配置 以上代码运行完,会在根目录生成config文件夹 进入 config > webpack.config.js 查找…...

基于JavaWeb的学生管理系统

文章目录 项目介绍主要功能截图:登录用户信息管理院系信息管理班级信息管理新增学生课程管理成绩管理部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系�…...

win11右键新建菜单添加选项

需要操作 2 处注册表, 以下以在右键新建菜单中添加 .html 为例 在主键 HKEY_CLASSES_ROOT 中,搜索 .html 找到后 ,右键点击它,选 新建 ->项, 在这里插入图片描述 项目名字是:ShellNew 新建后&#x…...

leetcode Day5(卡线复试,放弃版)

Day5 最后一个单词长度(要求最后一个,可以反向计数) int lens.length()-1; while(s.charAt(len)){len--;//最后是一个空格,就是无字符时 } int wordlen0;//记录字符长度 /*charAt() 方法用于返回指定索引处的字符。索引范围为从 0…...

cmake 入门二 库的编译,安装与使用

工程描述 1,建立一个静态库和动态库,提供HelloFunc 函数供其他程序编程使用,HelloFunc 向终端输出Hello World字符串。 2,安装头文件与共享库。 1 库的工程结构 1.1 工程目录下的CMakeLists.txt PROJECT…...

Python中实现将内容进行base64编码与解码

一、需求说明需要使用Python实现将内容转为base64编码,解码,方便后续的数据操作。二、base64简介Base64是一种二进制到文本的编码方式【是一种基于 64 个可打印字符来表示二进制数据的表示方法(由于 2^664,所以每 6 个比特为一个单…...

集合TreeSet的使用-java

TreeSet的特点:可排序、不重复、无索引。可排序:按照元素的大小默认升序排序;底层是基于红黑树的数据结构实现排序的,增删改查性能都较好。对于数值、字符串类型的(Integer 、Double、String)TreeSet可以排…...

Mybatis-plus 分页集成以及基本使用总结 入门和案例 注解连表查询分页案例等

简介 Mybaits-plus 是mybits 的升级版,从mybaits 升级到mybaits-plus 可以实现平滑升级 Mybaits-plus 本身提供了大量的基本查询方法以及强大的 Wrapper(包装) 类 用于查询的 QueryWrapper 以及 更新的 UpdateWrapper ,使用Wrapper 基本已经可以构建大…...

5个设计师常用素材库

推荐5个设计素材网站,免费下载! 1、菜鸟图库 菜鸟图库-免费设计素材下载 菜鸟图库是一个素材量非常丰富的网站,该网站聚合了平面、UI、淘宝电商、高清背景图、图片、插画等高质量素材。平面设计模板非常多,很多都能免费下载&…...

PHP/7.2.11 缺少 apache2/logs/httpd.pid 文件

启动服务时:systemctl restart httpd.service,报错:● httpd.service - httpd serviceLoaded: loaded (/etc/systemd/system/httpd.service; enabled; vendor preset: disabled)Active: failed (Result: exit-code) since 五 2023-02-24 16:1…...

【centos7下部署mongodb】

一.安装环境 CentOS7MongoDB4.0.13正式版。 二.下载MongoDB 1.1 官网下载地址:https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.13.tgz 1.2 将压缩包通过xftp上传到服务器/opt目录,然后解压、改名 三. 配置环境变量及配置文件 3.1配置系…...

pycharm首次使用爬虫框架scrapy遇到的问题和解决方法(二)

在首次使用scrapy框架的过程中,一直是对着别人的框架步骤撸代码的。然而,撸着撸着发现好像别人的也用不了。后面就只能自己找踏坑了。 问题报错: 1,IndexError: list index out of range 2,pymysql.err.ProgrammingError: (1064, "You have an error in your SQL s…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

基于FPGA的PID算法学习———实现PID比例控制算法

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

C++ 基础特性深度解析

目录 引言 一、命名空间(namespace) C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用(reference)​ C 中的引用​ 与 C 语言的对比​ 四、inline(内联函数…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...