5件关于JavaScript中this参数的事

news/2024/10/30 17:28:01/

this 关键字是 JavaScript 中最令人困惑的部分之一,本文试图通过介绍有关它的五个重要事项来阐明其目的和用法。

1、它允许访问同一对象上的其他属性

在 JavaScript 中,函数可以是独立的单元,但它们也可以用作对象的值。考虑下一个对象。

const obj = {msg: 'Hi',logMessage: function(){}
}

logMessage 属性存储一个函数,logMessage 是一种方法。

logMessage 函数如何访问同一对象上的其他成员?

这是这个伪参数变得有用的地方,它允许访问同一对象上的其他成员。

const obj = {msg: 'Hi',logMessage: function(){console.log(this.msg);}
}
obj.logMessage();
//'Hi'

在 logMessage 方法中,this 关键字用于访问同一对象的 msg 属性。

基本上,这就是在 JavaScript 中使用 this 关键字的原因,它允许访问其他拥有或继承的属性。

这种行为只有一个条件,函数应该作为方法调用,而不是作为函数调用。

2、它取决于函数的调用方式而不是函数的定义位置

考虑以下访问 this 参数的函数。

this.msg = "Parent";
function logMessage(){console.log(this.msg);
}

在下一个示例中,对两个对象使用相同的函数。

const obj = {msg: 'Hi',logMessage
}
const newObj = {msg: 'Hello',logMessage
}

这个变量引用的对象是什么?

这取决于函数的调用方式,而不是函数的定义位置。

当 logMessage 作为 obj 对象上的方法调用时,它引用该对象。

obj.logMessage();
//'Hi'

当它作为 newObj 对象上的方法被调用时,它指向它。

newObj.logMessage();
//'Hello'

请考虑以下示例,其中 logMessage 属性存储在 obj 对象内定义的函数。

const obj = {msg: 'Hi',logMessage: function(){console.log(this.msg);}
}

logMessage 中的 this 参数是否总是引用 obj 对象,因为它是在该对象中定义的?

答案是,NO。

下面是调用 logMessage 并使用 call 方法传递由 this 参数引用的不同对象的示例。

const newObj = {msg: 'Hello'
}
obj.logMessage.call(newObj);
//'Hello'

同样可以使用 apply 方法来完成,我们甚至可以强制它使用空对象运行,这次函数记录未定义。

obj.logMessage.apply({});
//undefined

3、与函数形式一起使用时,它指向其他东西

函数不一定是对象的一部分,它们可以是独立的单元,因此,可以用函数形式调用。

考虑下一个例子。

const obj = {msg: 'Hi',logMessage: function(){console.log(this.msg);}
}
const logMessage = obj.logMessage;
logMessage();
//undefined

logMessage 中的 this 不依赖于函数的定义位置,在这种情况下是在 obj 对象中。

这取决于如何调用 logMessage,在前面的示例中,logMessage 被调用为函数而不是方法。这指向了一些意想不到的东西,this.msg 给出了未定义的内容。

这是另一个例子。

const obj = {msg: '',logMessage: function(){this.msg = 'Hi';function logSomething(){console.log(this.msg);}logSomething();}
}
obj.logMessage();
//undefined

logMessage 作为方法调用(obj.logMessage()),但 logSomething 作为函数调用。因为 logSomething 不是作为方法调用,而是作为函数调用,所以,在其中 this 指向未例外的东西。在这种情况下,this.msg 给出未定义。

如果您希望 this 引用正确的对象,请确保始终将 logMessage 作为方法调用。

4 、箭头函数没有this

确实箭头函数没有自己的 this。它们实际上是用来解决我们之前在方法内部调用内部函数时遇到的问题。

检查下一个示例。

const obj = {logMessage: function(){const msg = 'Hi';const logSomething = ()=>{console.log(msg);}logSomething();}
}
obj.logMessage();
//'Hi'

logSomething 是否将 msg 作为变量?不。

logSomething 在尝试访问它没有的变量时会发生什么?

它向下看它的父级元素来找到变量并使用它。

据说箭头函数没有自己的 this,它实际上是什么意思?

这意味着它看不起它的父级元素来找到变量并使用它。

看下面的例子。

const obj = {msg: '',logMessage: function(){this.msg = 'Hi';const logSomething = ()=>{console.log(this.msg);}logSomething();}
}
obj.logMessage();
//'Hi'

logSomething 没有这个参数,与从外部环境中使用的其他变量和参数一样,它向下查看链并在其父级中找到它并使用它。

logSomething 中的 this 与 logMessage 中的对象相同。

5、应用程序可以在不使用它的情况下编写

除非应用程序已经以这种方式编写,否则无需使用 this 关键字编写应用程序。

像 React Hooks、VueJs Composition API 和 Svelte 这样的 UI 框架允许在不使用 this 关键字的情况下编写组件。

我们可以使用闭包来编写封装对象,这是一个例子。

const obj = (function(){let msg = '';function logMessage(){msg = 'Hi';const logSomething = ()=>{console.log(msg);}logSomething();}return {logMessage}
})();
obj.logMessage();
//'Hi'

logMessage 是在自执行函数内部定义的内部函数。logMessage 是一个闭包。它从外部函数引用 msg 变量。即使在自执行函数返回后,它也可以访问此变量。

现在它不关心我们是否将 logMessage 作为函数或作为方法调用,它总是引用正确的 msg 变量。

const logMessage = obj.logMessage;
logMessage();
//'Hi'

写在最后的想法

如果您真的想使用 this 关键字,或者受限于应用程序内部已经做出的决定,请记住该函数应作为方法调用以指向正确的对象。

如果真的不喜欢使用 this 关键字,您也可以考虑使用闭包实现对象并完全避免使用 this。


http://www.ppmy.cn/news/60375.html

相关文章

怎样在docker中使用macvlan创建可以独立ip访问的容器

怎样在docker中使用macvlan创建可以独立ip访问的容器 macvlan是什么macvlan的小demo1.设置Centos7的端口转发功能2.在docker中创建macvlan3.创建docker容器时指定相应的ip地址 macvlan是什么 macvlan是一种网络虚拟化技术,它允许在一个物理网络接口上配置多个虚拟网…

在体育新闻文本中提取关键词可以使用什么技术

在体育新闻文本中提取关键词可以使用以下技术: 1. 领域词典: 通过构建体育领域的词汇表,将其中的词语作为关键词,可以较好地提取体育新闻中的关键词。 就当下的研究情况,国内外有哪些体育领域的词汇表http://t.csdn…

单机版部署Redis详细教程

概述 大多数企业都是基于Linux服务器来部署项目,而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis. 此处选择的Linux版本为CentOS 7. Redis的官方网站地址:https://redis.io/ 单机安装Redis 1.1.安装Redis依…

如何批量修改删除html文件中的标签属性

最近工作中遇到一个问题,一份html文档因为内容里面的样式标签过多导致文件整体过大。 这些描述标签不是必须的,现在需要优化删除掉这些标签从而减小文件体积。 对于这种批量修改删除的任务,我们首先想到的就是使用编辑器处理。 编辑html文…

ESP32-设备驱动TMP102数字温度传感器驱动

TMP102数字温度传感器驱动 文章目录 TMP102数字温度传感器驱动1、TMP102介绍2、硬件准备3、软件准备4、驱动实现1、TMP102介绍 TMP102 器件是一款数字温度传感器,非常适合需要高精度的 NTC/PTC 热敏电阻更换。 该器件提供 0.5C 的精度,无需校准或外部组件信号调理。 器件温度…

InnoDB 与MyISAM 的区别

MyISAM和InnoDB都是Mysql里面的两个存储引擎。 在Mysql里面,存储引擎是可以自己扩展的,它的本质其实是定义数据存储的方式以及数据读取的实现逻辑。 不同存储引擎本身的特性,使得我们可以针对性的选择合适的引擎来实现不同的业务场景。从而获…

数据库基础操作

数据库 1. 概述2. 详述3. 创建数据库表4. 增加数据库记录5. 修改和删除数据库记录6. 修改和删除数据库表7.非外键约束8.外键约束9.外键策略10.杂项-快速拷贝表11.表的准备12.单表查询13.where子句14. 单行多行函数15. group by 和 having 1. 概述 数据库的基础操作主要分为六块…

Vue2对Axios封装使用

安装排错流程: 1.安装npm i axios 安装是否成功 2.创建 src\utils\require.js 文件夹 axios.create({ }) // 指定baseURL http://127.0.0.1:8080/.... 3.导出 实例化的axios 4.引入到main.js 挂在到Vue实例上 5. import requset from "../utils/requi…