执行上下文,js、React、HTML中的this

news2025/1/10 2:10:05

目录

执行上下文属性:变量对象、this,作用域链

变量对象是与执行上下文相关的数据作用域,存储:变量、函数声明

执行上下文生命周期

创建:生成变量对象、创建函数作用域,建立作用域链、确定this的指向

执行:变量赋值、函数的引用(调用时用指针)、执行其他代码

全局执行上下文:this 指向window全局对象

函数执行上下文:每次调用会创建新的执行上下文

()=>{}应用:共享外部函数的执行上下文(this、性能优化)

作用域:可访问变量的集合

全局作用域

函数作用域:在函数定义的时候就决定了

块级作用域(ES6):{}

作用链=作用域链表

查找不到:原型链undefined,作用域链ReferenceError

this:谁调用就指向谁,除非绑定

全局环境(普通函数/匿名函数):window/undefined 严格模式

JS

非严格模式:对象

严格模式:任意值

改变this中的thisArg

new 运算符构造绑定函数:提供的 this 值会被忽略(因为构造函数会准备自己的 this

new.target

原始值转换为对象:->Number/String

全局对象替换:null/undefined->window(非严格模式)

bind

HTML

React的class实例

执行上下文属性:变量对象、this,作用域链

const ExecutionContextObj = {
    VO: window, // 变量对象
    ScopeChain: {}, // 作用域链
    this: window
};

变量对象是与执行上下文相关的数据作用域,存储:变量、函数声明

生成变量对象:

  • 创建arguments
  • 扫描函数声明
  • 扫描变量声明

执行上下文生命周期

创建:生成变量对象、创建函数作用域,建立作用域链、确定this的指向

执行:变量赋值、函数的引用(调用时用指针)、执行其他代码

全局执行上下文:this 指向window全局对象

函数执行上下文:每次调用会创建的执行上下文

()=>{}应用:共享外部函数的执行上下文(this、性能优化)

//函数内部找不到就会去外层作用域
function foo() {
  console.log(a);
}

function bar() {
  let a="bar"
  foo(); 
}
let a="window"
bar(); //window

浏览器调试工具

作用域:可访问变量的集合

作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突

全局作用域

函数作用域:在函数定义的时候就决定了

块级作用域(ES6):{}

作用链=作用域链表

查找不到:原型链undefined,作用域链ReferenceError

this:谁调用就指向谁,除非绑定

全局环境(普通函数/匿名函数):window/undefined 严格模式

// 整个脚本都开启严格模式的语法
"use strict";
var v = "Hi!  I'm a strict mode script!";

JS

当前执行上下文(global、function 或 eval)的一个属性:this

可以使用 globalThis 获取全局对象,无论你的代码是否在当前上下文运行。

非严格模式对象

严格模式任意值

如果进入执行环境时没有设置 this 的值,this 会保持为 undefined

function f2() {
  "use strict"; // 这里是严格模式
  return this;
}

f2() === undefined; // true

改变this中的thisArg

new 运算符构造绑定函数:提供的 this 值会被忽略(因为构造函数会准备自己的 this

new.target
//如果构造函数是通过 new 运算符来调用的,则 new.target 将指向构造函数本身,否则它将是 undefined
//new.target 是一个在构造函数中可用的元属性(meta-property),用于检查构造函数是如何被调用的。而 Base 是一个类(或构造函数)的名称
class Base {
  constructor(...args) {
    console.log(new.target === Base);
    console.log(args);
  }
}

const BoundBase = Base.bind(null, 1, 2);

new BoundBase(3, 4); // true, [1, 2, 3, 4]
function Greet(name) {
  this.name = name;
}

const person = {
  name: "Alice"
};

// 使用 bind 创建绑定函数,将 this 设置为 person
const boundGreet = Greet.bind(person, "Bob");

// 使用 new 运算符尝试构造绑定函数
const newGreet = new boundGreet();

console.log(newGreet.name); // 输出 "Bob",而不是 "Alice"

原始值转换为对象:->Number/String

期望 this 是一个对象,但 thisArg 参数是一个原始值(比如数字、字符串等),则 thisArg 会被转换为对应的包装对象。例如,如果 thisArg 是一个数字,它将被转换为 Number 包装对象

严格模式下,不允许将原始值(如字符串、数字、布尔值)包装为对应的对象(String、Number、Boolean),而是保持它们的原始类型

"use strict"; // 防止 `this` 被封装到到包装对象中

function log(...args) {
  console.log(this, ...args);
}
const boundLog = log.bind("this value", 1, 2);
const boundLog2 = boundLog.bind("new this value", 3, 4);
boundLog2(5, 6); // "this value", 1, 2, 3, 4, 5, 6
//不用严格模式,则输出{"this value"}, 1, 2, 3, 4, 5, 6

全局对象替换:null/undefined->window(非严格模式)

如果 thisArg 参数传入了 nullundefined,在非严格模式下,它们会被替换为全局对象(通常是 window 对象)。这是为了确保函数始终有一个合法的 this 对象,防止出现错误。在严格模式下,nullundefined 不会被替换,函数内部的

"use strict"; // 防止 `this` 被封装到到包装对象中

function log(...args) {
  console.log(this, ...args);
}
const boundLog = log.bind("this value", 1, 2);
const boundLog2 = boundLog.bind("new this value", 3, 4);
boundLog2(5, 6); // "this value", 1, 2, 3, 4, 5, 6

this 将保持为 nullundefined

bind

const module = {
  x: 42,
  getX: function () {
    return this.x;
  },
};

const unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// Expected output: undefined

const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// Expected output: 42

绑定函数将绑定时传入的参数(包括 this 的值和前几个参数)提前存储为其内部状态。而不是在实际调用时传入。

通常情况下,你可以将 const boundFn = fn.bind(thisArg, arg1, arg2) 和 const boundFn = (...restArgs) => fn.call(thisArg, arg1, arg2, ...restArgs) 构建的绑定函数的调用效果视为等效

绑定函数可以通过调用 boundFn.bind(thisArg, /* more args */) 进一步进行绑定,从而创建另一个绑定函数 boundFn2。新绑定的 thisArg 值会被忽略,因为 boundFn2 的目标函数是 boundFn,而 boundFn 已经有一个绑定的 this 值了。

HTML

<button onclick="click(this)">传进去的为当前button</button>
<button onclick="click()">click()中直接使用this为window</button>

React的class实例

  

import React, { Component } from 'react'; // 请确保导入 React 和 Component

class APP extends Component {
  constructor(props) {
    super(props);
    // 将 handleClick 方法绑定到组件实例的上下文
    this.handleClick5 = this.handleClick5.bind(this);
  }
  handleClick1(ev) {
    console.log(this);//undefined
    console.log(ev);//合成的SyntheticBaseEvent 
    console.log(ev.target);//button
  }
  //箭头函数
  //方法A:类中箭头
  handleClick2 = () => {
    console.log(this);//APP类组件实例
  }
  //方法B:onclick中箭头
  handleClick3() {
    console.log(this);//APP类组件实例
  }
  // bind绑定组件实例this
  // 方法A:onclick
  handleClick4() {
    console.log(this);   //APP类组件实例
  }
  // 方法B:constructor
  handleClick5() {
    console.log(this); //APP类组件实例  
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick1}>点击1</button>
        {/* 箭头函数 */}
        <button onClick={this.handleClick2}>点击2</button>
        <button onClick={() => { this.handleClick3() }}>点击3</button>
        {/* bind */}
        <button onClick={this.handleClick4.bind(this)}>点击4</button>
        <button onClick={this.handleClick5}>点击5</button>
      </div>
    );
  }
}

export default APP;

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

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

相关文章

jdk 21发布的意义

jdk 21 最大的功能是虚拟线程&#xff0c;是一种绿色线程&#xff08;具体可以看周志明老师的书籍《深入理解java虚拟机》&#xff09;&#xff0c;目前 jvm 与操作系统的线程是一一对应的关系。 使用了虚拟线程可以减少资源消耗&#xff0c;减少操作系统上下文切换&#xff0…

AIGC绘本——海马搬家来喽

随着ChatGPT的快速发展&#xff0c;人工智能领域也发生了翻天覆地的变化。今天&#xff0c;我们迎合科技潮流&#xff0c;利用AIGC的强大能力&#xff0c;可以创作很多精彩的作品&#xff0c;比如这样一本名为《海马搬家》的绘本&#xff08;注&#xff1a;此绘本根据同名儿童故…

strtok()函数的使用方法

strtok() 函数用于将字符串分割成子字符串&#xff08;标记&#xff09;。它在 C 语言中非常常用&#xff0c;可以通过指定分隔符来拆分原始字符串&#xff0c;并依次返回每个子字符串。 以下是 strtok() 函数的使用方法&#xff1a; #include <stdio.h> #include <…

RK3568平台开发系列讲解(驱动篇)RK3568 I2C总线介绍

🚀返回专栏总目录 文章目录 一、I2C 简介1.1、起始位1.2、停止位1.3、数据传输1.4、应答信号1.5、I2C 写时序1.6、I2C 读时序1.7、I2C 多字节读写时序二、RK3568 I2C 总线介绍沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将讲解RK3568 I2C总线特性。 一、…

【中文输入时没有了提示选项】

打开电脑时发现&#xff0c;输入中文时&#xff0c;下方一直没有出现提示文字的选项&#xff0c;可能是电脑自动更新兼容的问题&#xff0c;上网查询了解决方案&#xff0c;按照下方步骤可以得到解决&#xff1a; step1&#xff1a;window键i //打开设置窗口 step2&#xf…

软件项目测试用例评审

软件项目测试用例评审是确保测试计划的一部分&#xff08;即测试用例&#xff09;满足项目质量和要求的关键步骤之一。以下是一个通用的软件项目测试用例评审流程&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎…

UbuntuToGo | Ubuntu 22.04.6 VMware UEFI启动 VHD虚拟磁盘

Win下新建固定大小VHD磁盘 磁盘管理器 随便选一个磁盘 点击操作 创建固定大小VHD(多等一会儿 固定大小比较慢) VMware 中新建虚拟机 自定义 在选择磁盘之前全部默认&#xff0c;选择磁盘选择 使用现有虚拟磁盘 现有磁盘文件选择刚才新建的VHD文件(一定要是固定大小的VHD)…

在DFMEA实施过程中,如何区分预防措施和探测措施?

在FMEA分析中&#xff0c;我们常常需要在分析原因之后采取相应的改善措施&#xff0c;一般现行的控制方法有“预防”和“探测”两大类&#xff0c;但是很多情况下我们无法掌握两者的区别&#xff0c;在这里我们明确一下。 FMEA手册中对预防和探测是这样定义的&#xff1a; 预…

计网第五章(运输层)(八)(TCP的连接释放)

目录 一、基本概述 二、具体实现 三、经典问题之为什么客户进程不直接进入关闭状态&#xff1f; 四、保活计时器 一、基本概述 上篇博客&#xff08; 计网第五章&#xff08;运输层&#xff09;&#xff08;七&#xff09;&#xff08;TCP的连接建立&#xff09;&#xff…

LeetCode 面试题 05.01. 插入

文章目录 一、题目二、Java 题解 一、题目 给定两个整型数字 N 与 M&#xff0c;以及表示比特位置的 i 与 j&#xff08;i < j&#xff0c;且从 0 位开始计算&#xff09;。 编写一种方法&#xff0c;使 M 对应的二进制数字插入 N 对应的二进制数字的第 i ~ j 位区域&#x…

ID保持的人像生成

AIGC真实人像写真&#xff0c;也即输入一些图片&#xff0c;生成图片里对应人物在不同场景和风格下的图片。妙鸭相机作为AIGC领域一款成功的收费产品为大家展示了如何使用AIGC技术只需要少量的人脸图片建模&#xff0c;即可快速提供真/像/美的个人写真&#xff0c;在极短的时间…

MySQL报错:this is incompatible with sql_mode=only_full_group_by 解决方法

文章目录 项目场景&#xff1a;原因分析及解决方案&#xff1a;总结&#xff1a; 项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_modeonly_f…

一般做家庭用电的考什么样式的电工证?应急管理厅低压电工

一般做家庭用电的考什么样式的电工证&#xff1f;应急管理厅低压电工 就是普通家庭&#xff0c;企事业单位的用电安装维修的那种&#xff0c;是考什么电工证&#xff0c;很多人从事这个行业&#xff0c;不知道该考哪一种类型的电工证书&#xff0c;跑去问机构考哪一种证书。其…

大数据 Hive 数据仓库介绍

目录 一、​​数据仓库概念 二、场景案例&#xff1a;数据仓库为何而来&#xff1f; 2.1 操作型记录的保存 2.2 分析型决策的制定 2.3 OLTP 环境开展分析可行吗&#xff1f; 2.4 数据仓库的构建 三、数据仓库主要特征 3.1 面向主题性&#xff08;Subject-Orient…

nokov设置教程 2023.09

1软件安装 设置 屏幕分辨力 缩放问题 软件设置 以管理员身份运行 高DPI缩放行为 系统 软件界面 1 设置路径 全部数据存放于该文件夹下 右下角文件按钮 右键 选择目录 设置完后程序上面显示路径 2 电脑设置ip地址 以太网属性 版本4 查看以太网状态 是否千兆网 网速 …

Untiy UDP局域网 异步发送图片

同步画面有问题&#xff0c;传图片吧 using System.Text; using System.Net.Sockets; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using System.Net; using System; using System.Threading.Tasks; using Sy…

搭建ELK+Filebead+zookeeper+kafka实验(详细版)

一、ELKFilebeadzookeeperkafka架构 第一层&#xff1a;数据采集层&#xff08;Filebeat&#xff09; 数据采集层位于最左边的业务服务集群上&#xff0c;在每个业务服务器上面安装了filebead做日志收集&#xff0c;然后把采集到的原始日志发送到kafkazookeeper集群上。 第二…

【常用代码15】文字单词超出强制分割换行,word-break: break-all;和word-wrap: break-word;的区别

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 文件上传后显示文件名&#xff0c;名称过长&#xff0c;超出div 有些文件名如下图 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 一般图片上传&#xff0c;要展示文件名&#x…

精品Python数字藏品购物商城爬虫-可视化大屏

《[含文档PPT源码等]精品基于Python实现的数字藏品爬虫》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;python 使用框架&#xff1a;Django 前端技术&#xff1a;JavaScript、VUE.js&a…

pytest简明教程

1. 简介 pytest是一款基于Python的测试框架。与Python自带的unittest相比&#xff0c;pytes语法更加简洁&#xff0c;断言更加强大&#xff0c;并且在自动测试以及插件生态上比unittest都要更加强大。 1.1. 安装pytest pip install pytest1.2. pytest命名规则 pytest默认会…