关于this

news2024/11/19 17:44:22

在这里插入图片描述

参考阮一峰老师对于this的原理理解

一:this的定义

严格模式下非严格模式下this的在全局中会有差别

来自阮一峰老师对于this的由来的理解

由于函数可以在不同的运行环境中运行,所以需要一种机制,能够在函数的内部获取当前运行环境,因此this就出现来,this的设计目的就是为了在函数的内部,指代函数当前的运行环境

所以在绝大多数的情况下,函数当前的运行环境决定了this的值

例如:

   var obj = {
      foo: function () { console.log(this.bar) },
      bar: 1
    };

    var foo = obj.foo;
    var bar = 2;

    obj.foo() // 1
    foo() // 2
  • 对于obj.foo()来说,是通过obj这个对象来找到foo(),所以foo()的运行环境obj对象,因此this的值就是Obj对象
  • 对于foo()来说,foo()函数的运行环境是window,因此this的值就是window
  • image-20230911205503092

二:绑定规则

根据不同的使用场合,this有不同的值,主要分为下面几种情况:

  • 默认绑定
  • 隐式绑定
  • new绑定
  • 显示绑定

1. 默认绑定

默认绑定的意思就是,当函数独立执行,不作为一个对象的方法调用时,this绑定到全局对象中,但在严格模式下,this会绑定到undefined

    function foo ()
    {
      console.log(this); // 在浏览器中通常指向 window 对象
    }

    foo();

2. 隐式绑定

当函数作为对象的方法调用时,this 绑定到调用该方法的对象

    var obj = {
      foo: function () { console.log(this) },
      bar: 1
    };

    var foo = obj.foo;

    obj.foo() // 1

这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象

    var obj = {
      a: {
        foo: function () { console.log(this) },
      },
      bar: 1
    };


    var foo = obj.foo;
    var bar = 2;

    obj.a.foo() 

foo执行的环境是a对象,所以this指向a对象

image-20230911210131323

再例如:

    var obj = {
      a: {
        bar: 1,
        foo: function ()
        {
          console.log(this.bar);	//2
          console.log(this)			//window
        },
      },

    };

    var bar = 2;

    const fn = obj.a.foo	
    fn()

  • 在该代码中,定义了一个变量fn,被将其赋值为obj.a.foo,这意味着fn现在引用了,obj对象中,a属性的foo方法。

  • 最后调用fn(),执行foo()函数

  • obj.a.foo复制给fn,只是将foo函数的引用复制给了fn,但并没有立即执行。所以fn只是函数的引用,它的上下文还是跟obj.a.foo相关

  • 但是当调用fn()时,这才是真正执行foo函数的时候,但由于fn是在全局上下文中调用的,JS将函数上下文this赋值为window

3. 显示绑定

使用 call()apply()bind() 方法显式地指定函数的 this 值。

    var obj = {
      foo: function () { console.log(this.bar) },
      bar: 1
    };

    var obj2 = {
      bar: 100
    }

    obj.foo.call(obj2)

image-20230911212217170

4. new 绑定

当函数用作构造函数(使用 new 关键字创建对象)时,this 绑定到新创建的对象。

    function fn ()
    {
      this.bar = 1
    }

    var obj = new fn()
    console.log(obj.bar);
  • 通过new关键字改变了this的执行,指向了obj

当函数返回一个对象

    function fn ()
    {
      this.bar = 1
      return {
        bar: 10
      }
    }

    var obj = new fn()
    console.log(obj.bar);
  • 当函数返回一个对象时,通过new关键字将this指向改变指向返回的对象,不指向obj
    • image-20230911212816249

当返回一些简单类型时候

    function fn ()
    {
      this.bar = 1
      return true
    }

    var obj = new fn()
    console.log(obj.bar);
  • this还是指向obj

返回null

    function fn ()
    {
      this.bar = 1
      return null
    }

    var obj = new fn()
    console.log(obj.bar);
  • 虽然null是object类型
  • 但是还是指向obj

三:箭头函数

JS中箭头函数与普通函数在this上有着重要的不同。

箭头函数this的绑定是在箭头函数创建的时候就确定的好的,是静态this绑定,它没有自己的上下文,它会捕获最近的普通函数的this

普通函数this值取决于,函数是如何被调用的,是根据调用方式动态确定的

在全局上下文中

    var a = 1
    const fn = () =>
    {
      console.log(this.a);
    }
    fn()

image-20230911214426329

  • fn箭头函数会自动捕获最近的最近的普通函数上下文,通常是全局对象window

在对象方法中

    var a = 10
    const obj = {
      a: 1,
      fn: () =>
      {
        console.log(this.a);
      }
    }
    obj.fn()

image-20230911214641724

  • fn箭头函数的this值不取决于被调用时动态绑定,而是在静态创建时候,与最近最近的普通函数上下文this值一致
  • fn箭头函数最近最近的普通函数上下文是window全局
  • 因此this指向window

作为事件回调

  <button id="btn">点击</button>

    const btn = document.getElementById('btn')
    var a = 10
    const obj = {
      a: 1,
      fn: () =>
      {
        console.log(this.a);		// 10
      }
    }
    btn.addEventListener('click', obj.fn)
  • 点击按钮输出还是10
  • 箭头函数作为回调函数时,其 this 绑定通常与定义它的上下文相同。

四:优先级

1. 隐式绑定 VS 显示绑定

function foo() {
    console.log( this.a );
}

var obj1 = {
    a: 2,
    foo: foo
};

var obj2 = {
    a: 3,
    foo: foo
};

obj1.foo(); // 2
obj2.foo(); // 3

obj1.foo.call( obj2 ); // 3
obj2.foo.call( obj1 ); // 2
  • 显示绑定优先级要高于隐式绑定

2. new绑定 VS 显示绑定

function Person(name) {
  this.name = name;
}

const alice = new Person("Alice");
const person = { name: "Bob" };

const boundGreet = greet.bind(person);
const aliceWithBinding = new boundGreet(); // 使用 new 绑定,this 绑定到新对象 aliceWithBinding
console.log(aliceWithBinding.name); // 输出: undefined,因为 new 绑定覆盖了显式绑定

  • new 绑定的优先级更高。当使用 new 关键字创建对象实例时,它会覆盖之前的显式绑定

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1001075.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据课程L6——网站流量项目的SparkStreaming

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解网站流量项目的SparkStreaming概述; ⚪ 掌握网站流量项目的SparkStreaming实现 Wordcount 底层流程; ⚪ 掌握网站流量项目的SparkStreaming实现历史批次的累积处理; ⚪ 掌握网站流…

Vue中使用Google的reCAPTCHA v3人机校验-demo

reCAPTCHA Google 提供了 reCAPTCHA&#xff08;v3 和 v2&#xff09;和 reCAPTCHA Enterprise&#xff0c;帮助您保护网站免受欺诈活动、垃圾内容和滥用行为的侵扰 reCAPTCHA v3 「所有的頁面都會有 reCaptcha 的追蹤功能」 不需做任何事&#xff0c;v3會針對使用者行為&#…

IDEA编写Java编程代码提示插件

网址&#xff1a; aiXcoder idea软件中使用代码提示&#xff1a; aixcoder

C语言实现扫雷小游戏

1.首先扫雷游戏要存储布置好的雷信息&#xff0c;需要一个二维数组 不是雷放* 雷&#xff1a;# 不是雷&#xff1a;0 雷&#xff1a;1 2. 给2个二维数组 9*9 一个存放雷的信息&#xff0c;一个存放布置好雷的信息 3.为了防止在统计坐标周围的…

回归与聚类算法系列④:岭回归

目录 1. 背景 2. 数学模型 3. 特点 4. 应用领域 5. 岭回归与其他正则化方法的比较 6、API 7、代码 8、总结 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数…

OLED透明屏控制:引领未来交互技术的创新突破

OLED透明屏控制技术作为一项颠覆性的显示技术&#xff0c;正逐渐改变我们与屏幕互动的方式。 其高透明度、触摸和手势交互、高画质和图像显示效果等特点&#xff0c;为用户提供了更智能、便捷的交互体验&#xff0c;同时也在各行各业中展现出无限的应用可能性。 在此&#xf…

【算法】反悔贪心

文章目录 反悔贪心力扣题目列表630. 课程表 III871. 最低加油次数LCP 30. 魔塔游戏2813. 子序列最大优雅度 洛谷题目列表P2949 [USACO09OPEN] Work Scheduling GP1209 [USACO1.3] 修理牛棚 Barn RepairP2123 皇后游戏&#xff08;&#x1f6b9;省选/NOI− TODO&#xff09; 相关…

Mybatis---resultMap详解

目录 一、resultMap介绍 二、自定义映射关系 一、resultMap介绍 该标签的作用是自定义映射关系。 Mybatis可以将数据库结果封装到对象中&#xff0c;是因为结果集和对象属性名相同&#xff08;也就是你写的pojo类型的参数名和数据库的字段名相同&#xff09; 但是如果当他们不…

【计算机网络】 TCP——四次挥手

文章目录 流程考点 流程 主动方打算关闭连接&#xff0c;此时会发送一个TCP首部FIN标志位被置为1的报文&#xff0c;也即FIN报文&#xff0c;之后主动方进入FIN_WAIT_1状态。被动方收到该报文后&#xff0c;就向主动方发送ACK应答报文&#xff0c;接着被动方进入CLOSE_WAIT状态…

HTML + CSS 实践1

Hello,小伙伴们 这是一个十分精美的网站&#xff0c;可以拿着它去制作一些个人网站 index.html <!DOCTYPE html> <meta charset"utf-8"> <html> <head> <title>首页</title> </head> <style type"text/css"…

【业务功能篇105】 微服务-springcloud-springboot-电商订单模块--秒杀服务-定时任务【上篇】

秒杀服务 一、商品上架 秒杀活动的结构图 通过定时任务触发&#xff1a; 定时任务由spring提供&#xff0c;需要通过注解开启&#xff0c;这里通过定义一个配置类&#xff0c;注入spring,对其配置类进行相应的注解&#xff0c;当然也可以注解放在我们的服务启动类上cron表达…

linux系统移植到开发板简要过程(移植bootloader引导加载程序---移植linux内核---制作根文件系统)

一.标准linux启动过程图 对于linux启动流程分析&#xff0c;我们需要移植bootloader引导加载程序---移植linux内核---制作根文件系统镜像文件&#xff1b; 二.为什么进行系统移植&#xff1f; 对于不同的硬件平台&#xff0c;linux系统启动流程大体相同&#xff0c;但是资源需求…

多线程的创建

一、基本概念 1 cpu CPU的中文名称是中央处理器&#xff0c;是进行逻辑运算用的&#xff0c;主要由运算器、控制器、寄存器三部分组成&#xff0c;从字面意思看就是运算就是起着运算的作用&#xff0c;控制器就是负责发出cpu每条指令所需要的信息&#xff0c;寄存器就是保存运…

spaCy库的实体链接踩坑,以及spaCy-entity-linker的knowledge_base下载问题

问题1. spacy Can’t find factory for ‘entityLinker’ 1&#xff09;问题 写了一个实体链接类&#xff0c;代码如下&#xff1a; nlp spacy.load("en_core_web_md")class entieyLink:def __init__(self, doc, nlp):self.nlp nlpself.doc self.nlp(doc)# Che…

MATLAB入门-矩阵的运算

MATLAB入门-矩阵的运算 本篇文章为学习笔记&#xff0c;课程链接为&#xff1a;头歌 相关知识 常见的矩阵运算有算术运算、关系运算和逻辑运算。MATLAB中的所有变量都是以矩阵的形式存储的&#xff0c;单个变量就相当于一个1*1的矩阵。 算术运算 下面展示的是常见的矩阵之…

云负载均衡

华为云&#xff1a;弹性负载均衡&#xff08;ELB&#xff09; 服务列表----弹性负载均衡 腾讯云&#xff1a;负载均衡 阿里云&#xff1a;弹性负载均衡&#xff08;SLB&#xff09;【ALB NLB CLB】 云服务&#xff1a; 云弹性负载均衡&#xff08;ELB/SLB&#xff09; 云服务…

Unity3D之简单溶解特效制作

文章目录 新建Shader Graph设置参数新建Step节点新建Simple Noise节点查看效果 新建Shader Graph 这里选择 Shader Graph -> URP -> Unlit Shader Graph 创建 设置参数 把 Surface Type 改成 Transparent 新建Step节点 创建一个Step的节点 把 Step 的 Out 连接到 Frag…

Java8-17 --- idea2022

目录 一、idea官网 二、使用idea编写hello world 三、查看工程中的JDK配置信息 四、详细设置 4.1、显示工具栏 4.2、默认启动项目配置 4.3、取消自动更新 4.4、选择整体主体与背景图 4.5、设置编辑器主题样式 4.5.1、编辑器主题 4.5.2、字体大小 4.5.3、修改注…

JS看板:bryntum taskboard 5.5.2 Crack

Bryntum 任务板是一个灵活的看板 Web 组件&#xff0c;可帮助您可视化和管理您的工作。 任务板非常灵活&#xff0c;允许您完全自定义卡片、列和泳道的渲染和样式。借助丰富的 API&#xff0c;您甚至可以在运行时打开或关闭功能。 在繁忙的团队中跟踪任务可能会令人畏惧。任务…

AMD GPU 内核驱动架构分析(一)

在Linux系统中&#xff0c;GPU驱动是集成在DRM框架中的&#xff0c;AMD GPU的内核驱动结构是一个复杂的软件堆栈&#xff0c;负责管理和控制AMD图形硬件&#xff0c;以便应用程序可以与GPU进行通信并利用其图形处理能力。以下是AMD GPU内核驱动的主要组成部分&#xff1a; 硬件…