深度解析javascript中的this(一)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 深度解析javascript中的this(一)

前言

       this 关键字是 JavaScript 中最复杂的机制之一。它是一个很特别的关键字,被自动定义在所有函数的作用域中。我记得自己从开始学习javascript开始就开始不停地被人问到关于this的知识,自己也从来不敢保证自己回答的是对的。毫无疑问,在缺乏清晰认识的情况下,this 对开发者来说完全就是一种魔法,这系列文章将就this做一个深度解析,帮助大家打破看似不可打破的魔法

正文

为什么需要使用this

       我们还是一如既往从一个例子开始看这个问题:

640.png

       这段代码可以在不同的上下文对象(me 和 you)中重复使用函数 identify() 和 speak(),不用针对每个对象编写不同版本的函数。如果不使用 this,那就需要给 identify()和 speak() 显式传入一个上下文对象。

640.png

       this 提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将 API 设计得更加简洁并且易于复用。随着你的使用模式越来越复杂,显式传递上下文对象会让代码变得越来越混乱,使用 this则不会这样。

对this的错误认知

       太拘泥于“this”的字面意思就会产生一些误解。有两种常见的对于 this 的解释,但是它们都是错误的。

指向函数自身

       人们很容易把 this 理解成指向函数自身,这个推断从英语的语法角度来说是说得通的。包括我,在初学javascript的时候常将this指向为当前的函数。针对这个问题我们举一些例子给大家说明:

640.png

       这个例子很直接地打破了我们之前的观点,foo.count的值是0,这表明this并不是指向foo函数本身,那么这里实际修改的count的是哪里的呢?可能有些同学猜到了,window.count这时候值为4。this的指向在不考虑箭头函数的情况下,会指向这个函数的调用者,而不是这个函数的本身, foo(i)的调用可以理解成window.foo(i),所以this也会指向到window。如果这里就是想要修改foo.count怎么办呢,就需要调整一下foo的调用

640.png

指向函数的作用域

       需要明确的是,this 在任何情况下都不指向函数的词法作用域。在JavaScript 内部,作用域确实和对象类似,可见的标识符都是它的属性。但是作用域“对象”无法通过 JavaScript代码访问,它存在于 JavaScript 引擎内部。这里出示一段一个公共社区中互助论坛的精华代码来给大家解释一下这个问题

640.png

       我们始终要牢记在不考虑箭头函数的情况下,this将指向函数的调用者,而全局作用域下的变量都被绑定在window上,所以this也会指向window。这里不难理解foo中的this会指向window,而bar呢,this也会指向window,别忘了之前我们说的javascript的作用域规则,javascript是词法作用域,函数的作用域只与它定义的位置有关,而不会因为bar在foo中被调用就有什么不同,全局环境下是没有a变量的,所以会有上述的问题

this指向函数调用者

       我们始终要牢记在不考虑箭头函数的情况下,this将指向函数的调用者,而全局作用域下的变量都被绑定在window上,所以this也会指向window。这里不对箭头函数的情况做一个额外说明,感兴趣的同学可以查阅别的文章,网上类似的文章资料也很多,但是这里可以稍稍提一下,箭头函数的this的指向是指向箭头函数的上下文作用域,这样的原因是因为箭头函数本身并没有调用者的说法

小结

       对于那些没有投入时间学习 this 机制的 JavaScript 开发者来说,this 的绑定一直是一件非常令人困惑的事。包括我自己,在认真研究this之前,对this可能更多地是一些很模糊的概念,始终牢记,在不考虑箭头函数的情况下,this指向函数的调用者,也不要因为调用的位置而影响自己的判断,javascript作用域规则采用词法作用域,无论在哪里调用,永远以定义的位置为基准

目录
相关文章
|
14天前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
11天前
|
存储 前端开发 JavaScript
JavaScript垃圾回收机制深度解析
【10月更文挑战第21】JavaScript垃圾回收机制深度解析
92 59
|
3天前
|
前端开发 JavaScript
JavaScript新纪元:ES6+特性深度解析与实战应用
【10月更文挑战第29天】本文深入解析ES6+的核心特性,包括箭头函数、模板字符串、解构赋值、Promise、模块化和类等,结合实战应用,展示如何利用这些新特性编写更加高效和优雅的代码。
9 0
|
18天前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
24 0
|
19天前
|
JavaScript API
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
46 0
|
19天前
|
JavaScript
深入解析:JS与Vue中事件委托(事件代理)的高效实现方法
深入解析:JS与Vue中事件委托(事件代理)的高效实现方法
24 0
|
19天前
|
存储 JavaScript 前端开发
Vue.js项目中全面解析定义全局变量的常用方法与技巧
Vue.js项目中全面解析定义全局变量的常用方法与技巧
29 0
|
25天前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
59 0
|
25天前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
49 0
|
25天前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
56 0

热门文章

最新文章

推荐镜像

更多