深度解析javascript中的this(一)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 深度解析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作用域规则采用词法作用域,无论在哪里调用,永远以定义的位置为基准

目录
相关文章
|
2月前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
2月前
|
存储 前端开发 JavaScript
JavaScript垃圾回收机制深度解析
【10月更文挑战第21】JavaScript垃圾回收机制深度解析
124 59
|
1月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
58 0
|
1月前
|
前端开发 JavaScript
JavaScript新纪元:ES6+特性深度解析与实战应用
【10月更文挑战第29天】本文深入解析ES6+的核心特性,包括箭头函数、模板字符串、解构赋值、Promise、模块化和类等,结合实战应用,展示如何利用这些新特性编写更加高效和优雅的代码。
49 0
|
2月前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
41 0
|
2月前
|
JavaScript API
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
167 0
|
2月前
|
JavaScript
深入解析:JS与Vue中事件委托(事件代理)的高效实现方法
深入解析:JS与Vue中事件委托(事件代理)的高效实现方法
58 0
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
77 2
|
3天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
3天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析

推荐镜像

更多