千锋教育-做有情怀、有良心、有品质的职业教育机构

手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

当前位置:首页  >  技术干货  > JavaScript内的this指向

JavaScript内的this指向

来源:千锋教育
发布人:qyf
时间: 2023-02-23 17:16:00 1677143760

JavaScript内的this指向

  ● 在 javascript 语言中, 有一个奇奇怪怪的 "关键字" 叫做 this

  ● 为什么说它是 奇奇怪怪 呢, 是因为你写出 100 个 this, 可能有 100 个解释, 完全不挨边

  ● 但是, 在你的学习过程中, 搞清楚了 this 这个玩意, 那么会对你的开发生涯有很大帮助的

  ● 接下来咱们就开始一点一点的认识一下 this

  this 初认识

  ● 看到 this, 先给他翻译过来 "这个"

  ● 到底啥意思呢 ?

  ○ 饭桌上, 你妈和你说, 你多吃点的这个

  ○ 商店里, 你媳妇和你说, 这个包 这个包 这个包 我都要

  ○ 宴会上, 你爸和人介绍说, 这个傻小子是我儿子

  ● 你看, 每一句话上都有 "这个", 但是每个 "这个" 都是一个意思吗 ? 并不

  ● 就像我们 js 内的 this 一样, 每一个 this 的意思都不一样

  ● 但是我们会发现

  ○ 在说话的过程中, "这个" 是和我们说话的手势有关系

  ● 在 js 内一个道理

  ○ this 的意思是和代码的 "手势" 有关系

  ● 例子 :

  ○ 当你媳妇手指着一个 LV 包的时候, 说的 "这个" 指代的就是 LV包`

  ○ 当你妈指着鱼香肉丝的时候说 "这个" 指代的就是 鱼香肉丝

  ○ 所以在 javascript 内的 this 是要看 "说这句话的代码手指向哪里了"

  ● 看看下面一段代码

  var box = document.querySelector('#box')

  box.onclick = function () {

  console.log(this)

  }

  ○ 当你点击 box 这个元素的时候, 会触发后面的函数

  ○ 然后函数一执行, 就会在控制台打印一下 this

  ○ 这里的 this 就是 box 这个元素

  ● 这就是一个非常简单的 this 指向的例子了

  ● 接下来我们就开始详细学习一下 this

  给你个概念

  ● this , 是一个指针形变量, 它动态的指向当前函数的运行环境

  ● "什么鬼东西, 我听不懂啊"

  ● 给一个私人的解释 : "根据 this 所在的函数是如何被调用的来决定 this 是什么"

  ● 举个栗子来看一下

  function fn() {

  console.log(this)

  }

  fn()

  // this 就是 window

  ● 因为 this 是在 fn 函数内, 所以 fn 函数的调用方式就决定了这个 this 是什么

  function a() {

  function b() {

  console.log(this)

  }

  b()

  }

  a()

  // this 就是 window

  ○ 因为 this 是在 b 函数内, 所以 b 函数的调用方式决定了 this 是什么, 和 a 函数没关系

  ● 就是这个意思

  ● 最后, 根据这些年的经验总结给出一个私人的概念, 要牢记

  ○ 函数的 this

  ○ 和函数定义在哪没关系

  ○ 和函数怎么定义没关系

  ○ 只看这个函数的调用方式

  ○ 箭头函数除外

  对象调用

  ● 对象调用, 就是利用一个对象作为宿主来调用函数

  ● 最简单的方式就是把函数写在一个对象内, 利用对象来调用

  // 对象内写一个函数

  const obj = {

  fn: function () { console.log(this) }

  }

  // 调用这个函数

  obj.fn()

  ○ 这时候, 我们调用了和这个对象内的 fn 函数

  ○ 调用方式就是利用对象调用的函数, 所以在这个函数内的 this 就是 obj 这个对象

  ○ 换句话说, 只要在这个函数内, 只要出现 this 就是这个对象

  全局调用

  ● 顾名思义, 全局调用就是直接调用一个全局函数

  function fn() {

  console.log(this)

  }

  fn()

  ○ 此时这个函数内的 this 就是 window

  ○ 可能有的小伙伴觉得疯了

  ○ 但是我们仔细思考一下, 你会发现

  ○ 其实 fn 因为是在全局上的, 那么其实调用的完整写法可以写成 window.fn()

  ○ 此时就回到了之前对象调用那条路上, 这样就通顺了

  奇怪的调用

  ● 这个时候, 有的小伙伴可能会想到一个问题, 如果这个函数不放在全局呢 ?

  const obj = {

  fn: function () {

  function fun() {

  console.log(this)

  }

  fun()

  }

  }

  obj.fn()

  ● 此时的 this 应该是什么呢 ?

  ● 按照之前的思路思考

  ○ obj.fn() 确实调用了函数, 但是 this 不是在 obj.fn 函数内, 是在 fun 函数内

  ○ fun() 确实也调用了函数, 但是我没有办法写成 window.fun()

  ○ 那么 this 到底是不是 window 呢, 还是应该是 obj 内

  ● 答案确实是 window, 这又是为什么呢 ?

  捋一下思路

  ● 说道这里, 我们会发现

  ● this 真的是好奇怪哦 o(* ̄︶ ̄*)o 搞不定了

  ● 要是按照这个方式, 我来回来去的得记多少种, 谁会记得下来呢

  ● 接下来(划重点)

  我用我代码三十年的经验给你总结出来了一些内容, 希望你能牢记

  this 的个人经验

  ● 首先, this 在各种不同的情况下会不一样

  ● 那么从现在开始我把我总结的内容毫无保留的传授给你

  经验一 :

  ● 在 js 的非严格模式下适用

  ● 在非箭头函数中适用

  ● 不管函数定义在哪, 不管函数怎么定义, 只看函数的调用方式

  ○ 只要我想知道 this 是谁

  ○ 就看这个 this 是写在哪个函数里面

  ○ 这个函数是怎么被调用的

  观察 this 在哪个函数内

  function fn() {

  console.log(this)

  }

  // this 在函数 fn 内, 就看 fn 函数是怎么被调用的就能知道 this 是谁

  const obj = {

  fn: function () {

  console.log(this)

  }

  }

  // this 在 obj.fn 函数内, 就看这个函数怎么被调用的就能知道 this 是谁

  const obj = {

  fn: function () {

  function fun() {

  console.log(this)

  }

  }

  }

  // 这个 this 是在 fun 函数内

  // 如果你想知道这个 this 是谁

  // 和 obj.fn 函数没有关系, 只要知道 fun 函数是怎么被调用的就可以了

  ● 一定要注意 : 你想知道的 this 在哪个函数内, 就去观察哪个函数的调用方式就好了

  一些常见的函数调用方式

  1. 普通调用

  ● 调用方式 : 函数名()

  ● this 是 window

  ● 只要你书写 "函数名()" 调用了一个函数, 那么这个函数内的 this 就是 window

  function fn() {

  console.log(this)

  }

  fn()

  // 这里就是 fn() 调用了一个函数, 那么 fn 内的 this 就是 window

  const obj = {

  fn: function () {

  function fun() {

  console.log(this)

  }

  fun()

  }

  }

  obj.fn()

  // 这里的 this 因为是在 fun 函数内

  // fun() 就调用了这个 fun 函数

  // 所以不用管 fun 函数写在了哪里

  // 这个 fun 函数内的 this 就是 window

  2. 对象调用

  ● 调用方式:

  ○ 对象.函数名()

  ○ 对象['函数名']()

  ● this 就是这个对象, 对象叫啥, 函数内的 this 就叫啥

  const obj = {

  fn: function () {

  console.log(this)

  }

  }

  obj.fn()

  // 因为 obj.fn() 调用了这个函数, 所以 obj.fn 函数内的 this 就是 obj

  const xhl = {

  fn: function () {

  console.log(this)

  }

  }

  xhl.fn()

  // 因为 obj.fn() 调用了这个函数, 所以 xhl.fn 函数内的 this 就是 xhl

  function fn() {

  const xhl = {

  fn: function () {

  console.log(this)

  }

  }

  xhl.fn()

  }

  fn()

  // 因为我们要观察的 this 是在 xhl.fn 这个函数内

  // 所以只需要关注这个函数是如何被调用的即可

  // 因为是 xhl.fn 调用了和这个函数, 所以函数内的 this 就是 xhl

  3. 定时器调用

  ● 调用方式

  ○ setTimeout(function () {}, 1000)

  ○ setInterval(function () {}, 1000)

  ● this 就是 window

  ● 一个函数不管是怎么定义的, 只要被当做定时器处理函数使用, this 就是 widnow

  setTimeout(function () {

  console.log(this)

  }, 1000)

  // 这里的 this 就是 window

  setInterval(function () {

  console.log(this)

  }, 1000)

  // 这里的 this 就是 window

  const xhl = {

  fn: function () {

  console.log(this)

  }

  }

  setTimeout(xhl.fn, 1000)

  // 这里的 xhl.fn 函数不是直接书写 xhl.fn() 调用的

  // 而是给到了 setTimeout 定时器处理函数

  // 所以这里的 this 就是 window

  4. 事件处理函数

  ● 调用方式

  ○ 事件源.on事件类型 = 事件处理函数

  ○ 事件源.addEventListener(事件类型, 事件处理函数)

  ● this 就是 事件源

  ● 只要是作为事件处理函数使用, 那么该函数内的 this 就是 事件源

  奥,对了,事件就是:在事件中,当前操作的那个元素就是事件源

  box.onclick = function () {

  console.log(this)

  }

  // 这里的 this 就是 box

  box.addEventListener('click', function () {

  console.log(this)

  })

  // 这里的 this 就是 box

  const xhl = {

  fn: function () {

  console.log(this)

  }

  }

  box.addEventListener('click', xhl.fn)

  // 这里的 xhl.fn 函数不是直接书写 xhl.fn() 调用的

  // 而是给到了 事件, 被当做了事件处理函数使用

  // 所以这里的 this 就是 事件源box

  const xhl = {

  fn: function () {

  console.log(this)

  }

  }

  box.onclick = xhl.fn

  // 这里的 xhl.fn 函数不是直接书写 xhl.fn() 调用的

  // 而是给到了 事件, 被当做了事件处理函数使用

  // 所以这里的 this 就是 事件源box

  5. 构造函数调用

  ● 调用方式

  ○ new 函数名()

  ● this 就是该构造函数的当前实例

  ● 只要和 new 关键字调用了, this 就是实例对象

  function fn() {

  console.log(this)

  }

  const f = new fn()

  // 这里的因为 fn 函数和 new 关键字在一起了

  // 所以这里的 this 就是 fn 函数的实例对象

  // 也就是 f

  const xhl = {

  fn: function () {

  console.log(this)

  }

  }

  const x = new xhl.fn()

  // 这里的 xhl.fn 也是因为和 new 关键字在一起了

  // 所以这里的 this 就是 xhl.fn 函数的实例对象

  // 也就是 x

  记清楚原则 :

  不管函数在哪定义

  不管函数怎么定义

  只看函数的调用方式

  经验二 :

  ● 在严格模式下适用

  ● 其实只有一个

  ○ 全局函数没有 this, 是 undefined

  ○ 其他的照搬经验一就可以了

  1. 非严格模式

  // 非严格模式

  function fn() {

  console.log(this)

  }

  fn()

  // 因为是在非严格模式下, 这里的 this 就是 window

  2. 严格模式

  // 严格模式

  'use strict'

  function fn() {

  console.log(this)

  }

  fn()

  // 因为是在严格模式下, 这里的 this 就是 undefined

  记清楚原则 :

  严格模式下

  全局函数没有 this

  是个 undefiend

  经验三 :

  ● 专门来说一下箭头函数

  ● 其实也只有一条

  ○ 推翻之前的所有内容

  ○ 箭头函数内没有自己的 this

  ○ 箭头函数内的 this 就是外部作用域的 this

  ● 换句话说, 当你需要判断箭头函数内的 this 的时候

  ○ 和函数怎么调用没有关系了

  ○ 要看函数定义在什么位置

  // 非箭头函数

  const xhl = {

  fn: function () {

  console.log(this)

  }

  }

  xhl.fn()

  // 因为是 非箭头函数, 所以这里的 this 就是 xhl

  // ==========================================================

  // 箭头函数

  const xhl = {

  fn: () => {

  console.log(this)

  }

  }

  xhl.fn()

  // 因为是 箭头函数, 之前的经验不适用了

  // 这个函数外部其实就是全局了, 所以这里的 this 就是 window

  // 非箭头函数

  box.onclick = function () {

  console.log(this)

  }

  // 因为是 非箭头函数, 这里的 this 就是 box

  // ==========================================================

  // 箭头函数

  box.onclick = () => {

  console.log(this)

  }

  // 因为是 箭头函数

  // 这个函数外部就是全局了, 所以这里的 this 就是 window

  // 非箭头函数

  const obj = {

  fn: function () {

  function fun() {

  console.log(this)

  }

  fun()

  }

  }

  obj.fn()

  // 因为是 非箭头函数, 所以 fun 函数内的 this 就是 window

  // ==========================================================

  // 箭头函数

  const obj = {

  fn: function () {

  const fun = () => {

  console.log(this)

  }

  fun()

  }

  }

  obj.fn()

  // 因为是 箭头函数

  // 那么这个 fun 外面其实就是 obj.fn 函数

  // 所以只要知道了 obj.fn 函数内的 this 是谁, 那么 fun 函数内的 this 就出来了

  // 又因为 obj.fn 函数内的 this 是 obj

  // 所以 fun 函数内的 this 就是 obj

  记清楚原则 :

  只要是箭头函数

  不管函数怎么调用

  就看这个函数定义在了哪里

  最后

  ● 好了

  ● 按照以上三个经验, 记清楚原则

  ● 那么在看到 this 就不慌了

tags:
声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。
10年以上业内强师集结,手把手带你蜕变精英
请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通
免费领取
今日已有369人领取成功
刘同学 138****2860 刚刚成功领取
王同学 131****2015 刚刚成功领取
张同学 133****4652 刚刚成功领取
李同学 135****8607 刚刚成功领取
杨同学 132****5667 刚刚成功领取
岳同学 134****6652 刚刚成功领取
梁同学 157****2950 刚刚成功领取
刘同学 189****1015 刚刚成功领取
张同学 155****4678 刚刚成功领取
邹同学 139****2907 刚刚成功领取
董同学 138****2867 刚刚成功领取
周同学 136****3602 刚刚成功领取
相关推荐HOT