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

400-811-9990
手机站
千锋教育

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

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

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

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:郑州千锋IT培训  >  技术干货  >  JavaScript 内的 this 指向

JavaScript 内的 this 指向

来源:千锋教育
发布人:lxx
时间: 2023-03-07 15:21:00

  ● 在 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 的时候

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

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

  记清楚原则 :

  只要是箭头函数

  不管函数怎么调用

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

  最后

  ● 好了

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

  ● 那么在看到 this 就不慌了

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

类的加载机制是什么

2023-03-21

如何定义Java变量?

2023-03-14

细节决定成败:探究Mybatis中javaType和ofType的区别

2023-03-09

最新文章NEW

java实现多线程的几种方式

2023-03-21

java编程spring框架的作用

2023-03-21

什么是java中的进制

2023-03-17

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>