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

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

目录

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对象

相关文章:

  • 烧结银遇上HBM:开启存储新时代
  • HTML 文本格式化
  • Docker 学习笔记:从入门到部署,实战演练全流程!
  • SpringBoot 自定义异常处理
  • 【HarmonyOS Next】鸿蒙加固方案调研和分析
  • 祝福语【算法赛】
  • ESP32驱动OV3660摄像头实现物体轮廓识别(摄像头支持红外夜视、边缘AI计算)
  • C++常用函数
  • SpringBoot统一响应类型3.1.1版本
  • 初识大模型——大语言模型 LLMBook 学习(一)
  • 计算机网络传输层
  • 电子学会—2024年月6青少年软件编程(图形化)四级等级考试真题——水仙花数
  • Python 动态规划(DP)套路总结
  • UE5从入门到精通之如何创建自定义插件
  • (数据结构)双向链表
  • 2025-03-09 学习记录--C/C++-PTA 习题11-1 输出月份英文名
  • BEVDepth: Acquisition of Reliable Depth for Multi-view 3D Object Detection 论文阅读
  • 代码随想录算法训练营第八天|Leetcode 151.翻转字符串里的单词 卡码网:55.右旋转字符串 字符串总结 双指针回顾
  • 基于Spring3的抽奖系统
  • 通义千问:Qwen2.5-0.5B模型架构解释
  • 网络域名费用多少钱/什么是seo
  • 干零活一天一结的平台/优化设计卷子答案
  • 网站建设市场前景如何/如何创建自己的域名
  • 网站备案流程/百度竞价推广联系方式
  • 企业网站模版/网站功能优化
  • 沈阳网站排名seo/竞价推广开户电话