【二】JavaScript能力提升---this对象

news2025/4/21 15:40:32

目录

this的理解

this的原理

事件绑定中的this

行内绑定

动态绑定

window定时器中的this


相信小伙伴们看完这篇文章,对于this的对象可以有一个很大的提升!

this的理解

对于this指针,可以先记住以下两点:

  1. this永远指向一个对象
  2. this的指向完全取决于函数调用的位置

对于第一点,不管在什么地方使用this,它必然会指向某个对象。

由于在JavaScript中,一切皆对象,运行环境也是对象,所以函数都是在某个对象下运行,而this就是“函数运行时所在的对象(环境)

但因为JavaScript支持运行环境动态切换,即:this的指向是动态的,很难确定this到底指向哪个对象,这是最让我们感到困惑的地方。

this的原理

function fun()
{
    console.log(this.s);
}

var obj = {
    s:'1',
    f:fun
}

var s = '2';

obj.f(); // 1
fun(); // 2

JS中,数组、函数、对象都是引用类型,在参数传递时也就是引用传递(传递内存地址)。

在上面代码中,obj有两个属性,但是f属性存储了一个函数名(函数的内存地址),于是在调用f方法时,通过f的值找到对应的内存地址就调用到了对应的函数。

下图是obj在内存中的表示:

在调动时就变成了下面这个样子:

下面,我们一条一条解释,相信看完这些解释,你会恍然大悟

关于obj.f()的调用

  • 调用objf方法时,js引擎先找到obj这个对象,随后在obj内存地址中找到f方法的地址,再调用f方法地址中的值(在这里这个值就是functiuon fun()这个函数的内存地址),于是成功调用这个函数。但由于该函数是经过:“js引擎 -> obj对象 ->f()”这么一个顺序调用的,因此此时fun()this指向它的运行环境,即obj对象

关于fun()的调用

  • 调用fun()时,js引擎要在整个<script>标签下搜寻“函数名为fun的函数”,因为是在整个<script>标签搜寻,故搜索到fun()函数时,运行环境固然在window对象下,该函数经过:“js引擎 -> 整个<script>环境(window对象) -> fun()”这个一个顺序调用的
var A = {
    name:'张三',
    f:function(){
        console.log('姓名:'+this.name);
    }
};

var B = {
    name:"李四"
};

B.f = A.f;
B.f(); // 姓名:李四
A.f(); // 姓名:张三

上面代码,仍然可以用我上面所说的来解释:

由于“函数”的传递是“引用传递”(传递内存地址),即此时B.f的值就是匿名函数的内存地址,故B.f()A.f()实际上调用的是“同一个内存地址的同一个函数

  • 调用B.f()时,js引擎根据B.f的值,找到对应的匿名函数,此时匿名函数的执行环境在B对象之下,故打印“李四”
  • 调用A.f()时,js引擎根据A.f的值,找到对应的匿名函数,此时匿名函数的执行环境在A对象之下,故打印“张三”

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

var obj2 = {
    a:2,
    f:foo
};

var obj1 = {
    a:1,
    o:obj2
};

obj1.o.f(); // 2

对于上面代码,仍仍仍然可以使用刚才所说的来解释:

  • 调用obj1.o.f()时,js引擎根据obj1.o(obj2的内存地址)先找到obj2对象,再根据f(foo的内存地址)找到foo,最后执行foo。此时整个调用关系为:“js引擎 -> obj1对象 -> obj2对象 -> foo()”,故foo运行在obj2对象之下,因此打印2

事件绑定中的this

事件绑定有三种方式:行内绑定动态绑定事件监听

行内绑定

<input type="button" value="按钮" onclick="clickFun()">
<script>
    function clickFun(){
        this // window
    }
</script>
​
<input type="button" value="按钮" onclick="this">
<!-- 本节点对象 -->

节点事件属性的值可以是:“可执行的JS代码段”或“函数名(函数调用)

对于οnclick="clickFun()"

  • JS引擎发现onclick的值是函数调用,因此转去<script>标签下(window环境)寻找函数名为“clickFun”的函数,找到clickFun函数后成功执行。此时执行顺序为:“JS引擎 -> <script>标签 -> clickFun()

对于οnclick="this"

  • JS引擎发现onclick的值是一段可执行的js代码,因此JS引擎直接在该DOM节点下执行该代码,对应的this就指向该节点了

动态绑定

<input type="button" value="按钮" id="btn">
<script>
    var btn = document.getElementById('btn');
    btn.onclick = function(){
        this ;  // this指向btn节点对象
    }
</script>

这里的操作,本质上是直接对btn节点对象的onclick属性附一个值

当执行时,JS引擎发现onclick属性的值是一个匿名函数,因此直接就执行该匿名函数。

又因为该匿名函数的是在btn对象之下执行的,因此this执行btn节点对象

window定时器中的this

var obj = {
    fun:function(){
        this ;
    }
}
​
setInterval(obj.fun,1000);      // window对象
setInterval('obj.fun()',1000);  // obj对象

对于obj.fun:

注意:在这里有一个很重要的点,这里传入的是obj.fun,而不是obj.fun(),传递obj.fun是传入的fun这个方法函数(可以理解为传入fun的值,而fun的值是一个匿名函数,即匿名函数的地址)。而obj.fun是直接调用obj.fun()方法

  • 在经过1s后,JS引擎发现setInerval的第一个参数值是一个函数地址,因此转而去执行该函数。但由于setInterval是一个异步函数,在等待时,会将该代码段挂载到全局对象(window对象)下的一个栈中,因此执行过程为:“JS引擎 -> window对象下的栈 -> 匿名函数”,故this指向window对象

对于'obj.fun()'

  • 在经过1s后,JS引擎发现setInterval的第一个参数值是一段可执行的JS代码,转而执行这个代码,这个代码是调用obj.fun()对象,因此JS引擎去<script>标签(window)下找到obj对象,在找到fun方法,最后执行匿名函数。因此执行过程为:“JS引擎 -> window对象 -> obj对象 -> 匿名函数”,故this指向obj对象

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

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

相关文章

<论文>MiniCPM:利用可扩展训练策略揭示小型语言模型的潜力

一、摘要 本文跟大家一起阅读的是清华大学的论文《MiniCPM: Unveiling the Potential of Small Language Models with Scalable Training Strategies》 摘要&#xff1a; 对具有高达万亿参数的大型语言模型&#xff08;LLMs&#xff09;的兴趣日益增长&#xff0c;但同时也引发…

SpringCloud系列教程(十三):Sentinel流量控制

SpringCloud中的注册、发现、网关、服务调用都已经完成了&#xff0c;现在就剩下最后一部分&#xff0c;就是关于网络控制。SpringCloud Alibaba这一套中间件做的非常好&#xff0c;把平时常用的功能都集成进来了&#xff0c;而且非常简单高效。我们下一步就完成最后一块拼图Se…

ArcGIS操作:15 计算点的经纬度,并添加到属性表

注意&#xff1a;需要转化为地理坐标系 1、打开属性表&#xff0c;添加字段 2、计算字段&#xff08;以计算纬度为例 !Shape!.centroid.Y ) 3、效果

蓝桥杯历年真题题解

1.轨道炮&#xff08;数学模拟&#xff09; #include <iostream> #include <map> using namespace std; const int N1010; int x[N],y[N],v[N]; char d[N]; int main() {int n;int ans-100;cin>>n;for(int i1;i<n;i)cin>>x[i]>>y[i]>>v…

IP-地址

主机号&#xff08;Host ID&#xff09; IP地址简介&#xff1a;IP地址是每台接入互联网的设备所拥有的唯一标识符&#xff0c;类似于电话号码的分层结构&#xff0c;由网络号和主机号组成。为了便于记忆&#xff0c;32位二进制的IP地址通常以点分十进制表示。 网络号&#xf…

2025-03-08 学习记录--C/C++-PTA 习题10-1 判断满足条件的三位数

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 裁判测试程序样例&#xff1a; #include <stdio.h> #include <math.h>int search( int n );int…

三星首款三折叠手机被曝外屏6.49英寸:折叠屏领域的新突破

在智能手机的发展历程中,折叠屏手机的出现无疑是一次具有里程碑意义的创新。它打破了传统手机屏幕尺寸的限制,为用户带来了更加多元和便捷的使用体验。而三星,作为手机行业的巨头,一直以来都在折叠屏技术领域积极探索和创新。近日,三星首款三折叠手机的诸多细节被曝光,其…

LINUX网络基础 [五] - HTTP协议

目录 HTTP协议 预备知识 认识 URL 认识 urlencode 和 urldecode HTTP协议格式 HTTP请求协议格式 HTTP响应协议格式 HTTP的方法 HTTP的状态码 ​编辑HTTP常见Header HTTP实现代码 HttpServer.hpp HttpServer.cpp Socket.hpp log.hpp Makefile Web根目录 H…

WPS Word中英文混杂空格和行间距不一致调整方案

文章目录 问题1&#xff1a;在两端对齐的情况下&#xff0c;如何删除参考文献&#xff08;英文&#xff09;的空格问题2&#xff1a;中英文混杂行间距不一致问题问题3&#xff1a;设置中文为固定字体&#xff0c;设置西文为固定字体参考 问题1&#xff1a;在两端对齐的情况下&a…

CSDN博客:Markdown编辑语法教程总结教程(中)

❤个人主页&#xff1a;折枝寄北的博客 Markdown编辑语法教程总结 前言1. 列表1.1 无序列表1.2 有序列表1.3 待办事项列表1.4 自定义列表 2. 图片2.1 直接插入图片2.2 插入带尺寸的图片2.3 插入宽度确定&#xff0c;高度等比例的图片2.4 插入高度确定宽度等比例的图片2.5 插入居…

电子学会—2024年月6青少年软件编程(图形化)四级等级考试真题——水仙花数

水仙花数 如果一个三位数等于它各个数位上的数字的立方和&#xff0c;那么这个数就是水仙花数&#xff0c;例如:153 111 555 333&#xff0c;153就是一个水仙花数。 1.准备工作 (1)保留默认角色小猫; (2)白色背景。 2.功能实现 (1)使用循环遍历所有三位数&#xff0c;把所…

JetBrains学生申请

目录 JetBrains学生免费授权申请 IDEA安装与使用 第一个JAVA代码 1.利用txt文件和cmd命令运行 2.使用IDEA新建项目 JetBrains学生免费授权申请 本教程采用学生校园邮箱申请&#xff0c;所以要先去自己的学校申请校园邮箱。 进入JetBrains官网 点击立即申请&#xff0c;然…

langchain系列(终)- LangGraph 多智能体详解

目录 一、导读 二、概念原理 1、智能体 2、多智能体 3、智能体弊端 4、多智能体优点 5、多智能体架构 6、交接&#xff08;Handoffs&#xff09; 7、架构说明 &#xff08;1&#xff09;网络 &#xff08;2&#xff09;监督者 &#xff08;3&#xff09;监督者&…

侯捷 C++ 课程学习笔记:深入理解智能指针

文章目录 每日一句正能量一、引言二、智能指针的核心概念&#xff08;一&#xff09;std::unique_ptr&#xff08;二&#xff09;std::shared_ptr&#xff08;三&#xff09;std::weak_ptr 三、学习心得四、实际应用案例五、总结 每日一句正能量 如果说幸福是一个悖论&#xff…

访问不了 https://raw.githubusercontent.com 怎么办?

修改 Hosts 文件&#xff08;推荐&#xff09;​ 原理&#xff1a;通过手动指定域名对应的 IP 地址&#xff0c;绕过 DNS 污染。 步骤&#xff1a; 1、访问 IPAddress.com&#xff0c;搜索 raw.githubusercontent.com&#xff0c;获取当前最新的 IPv4 地址&#xff08;例如 1…

大模型工程师学习日记(十五):Hugging Face 模型微调训练(基于 BERT 的中文评价情感分析)

1. datasets 库核心方法 1.1. 列出数据集 使用 d atasets 库&#xff0c;你可以轻松列出所有 Hugging Face 平台上的数据集&#xff1a; from datasets import list_datasets# 列出所有数据集 all_datasets list_datasets()print(all_datasets)1.2. 加载数据集 你可以通过 l…

子数组、子串系列(典型算法思想)—— OJ例题算法解析思路

一、53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; 算法代码&#xff1a; class Solution { public:int maxSubArray(vector<int>& nums) {// 1. 创建 dp 表// dp[i] 表示以第 i 个元素结尾的子数组的最大和int n nums.size();vector<int> dp(n…

Windows编程----进程的当前目录

进程的当前目录 Windows Api中有大量的函数在调用的时候&#xff0c;需要传递路径。比如创建文件&#xff0c;创建目录&#xff0c;删除目录&#xff0c;删除文件等等。拿创建文件的CreateFile函数做比喻&#xff0c;如果我们要创建的文件路径不是全路径&#xff0c;那么wind…

AVL树的介绍及实现

文章目录 &#xff08;一&#xff09;AVL的概念&#xff08;二&#xff09;AVL树的实现1.AVL树的结构2.AVL树的插入3.AVL树的查找 &#xff08;三&#xff09;检查一棵树是否是AVL树 &#xff08;一&#xff09;AVL的概念 AVL树是一棵高度平衡的二叉搜索树&#xff0c;通过控制…

快速生成viso流程图图片形式

我们在写详细设计文档的过程中总会不可避免的涉及到时序图或者流程图的绘制&#xff0c;viso这个软件大部分技术人员都会使用&#xff0c;但是想要画的好看&#xff0c;画的科学还是比较难的&#xff0c;现在我总结一套比较好的方法可以生成好看科学的viso图(图片格式)。主要思…