百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 行业知识 > 正文

JavaScript 内的 this 指向

citgpt 2024-11-25 10:03 4 浏览 0 评论

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

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

JavaScript 内的 this 指向

● 但是, 在你的学习过程中, 搞清楚了 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 就不慌了

相关推荐

Win7打开网页特别慢的原因?

经常打开Web的频繁用户的数量应该打开,因此,一旦网页的速度很慢,它会变得非常敏感。最近,Win7系统的用户发现他们打开了他们的网页,突然放慢了,绝不看网络速度和配置因素,最有可能是系统内存问题。如果...

电脑浏览器下载速度很慢怎么办

有网友反映自己的浏览器下载速度很慢怎么办?这种通过可能是浏览器缓存太多,没有优化等原因导致。下面小编就以几种常用的浏览器为例,给大家解答下...

网站打开慢的问题如何解决?

  当我们在浏览网页时,突然发现一个网站打不开或者加载速度非常慢,这时候你会不会感到很烦躁呢?别担心,今天我们就来教你解决网站打开慢的问题!  一、检查网络连接  我们需要确保自己的网络连接正常。请尝...

打开网页速度慢、下载速度慢、玩游戏延迟、频繁掉线的解决方法

影响实际上网速度的因素非常多,需要挨个做排查1、先排除是否是网络环境问题,可以核实以下情况,来判断是否是网络环境问题。(1)同一网络环境,如果其他电脑上网也很慢,则可判断是网络本身速度不快导致的。(2...

浏览器太卡、启动慢,教你一招提速至少一倍!

电脑端浏览器用久了都会有一个毛病那就是开启速度非常缓慢今天教大家一个小技巧可大大提升浏览器启动速度适用于QQ、360、搜狗等大多数浏览器提速效果非常明显启动速度至少要快一倍SpeedyFox支持平台:...

网站访问慢的排查方案(最详细)

说实话,比起网站打不开,网站访问慢更让人抓狂。因为造成网站访问慢的因素太多了,一般用户根本无从下手!任他千头万绪的问题,从以下三个方面入手,也能轻松破解访问慢的大难题:响应时间、执行时间、加载时间。...

电脑网页打开慢怎么办?金山毒霸电脑医生秒搞定

??在网络时代,上网是每天都会做的事,平时用手机上网比较多,但是工作的时候还是用电脑上网的,不管手机还是电脑都会越用越慢。有时会觉得,电脑配置也不低,每天都清理垃圾了都,网速也还行电脑怎么还上网这么慢...

家里wifi慢是怎么回事?教你几招提速方法

没WiFi,不成活!手机和WiFi之间,就像空调加棉被,谁也离不开谁。如今WiFi已经填满了我们生活的每个角落,很难想象,如果哪天没了网,世界会变成什么样!可是家里的WiFi是越用越慢,不知道有多少人...

连接路由器宽带测速正常,打开网页很慢?

电脑连接路由器后测试网速和申请的宽带一致,但打开网页的速度较慢,请参考以下步骤排查:1、更改DNS服务器电脑上获取的DNS服务器不稳定可能会导致打开网页较慢,可以在电脑的本地连接或无线连接手动设置DN...

手机打开网页非常慢,那是你用的浏览器不对!

今天世超独宠Android差友不知道大家平日里,在刷着微博浏览着新闻的时候有没有遇见过这样的情况:在你浏览的过程中,总会出现一些让你感兴趣的链接。这些链接可能是:”这个视频,女人不在家男人偷偷看!”“...

网站打开慢的原因有哪些?

网络能够为大家带来许多便利,现在的人们不管是在学习或者是工作当中都是离不开网络的。在网络中,各大网页和网站也是我们浏览信息的主要渠道。如果想要更加高效率的工作和学习的话,当然也离不开网站浏览速度的支持...

告诉你导致网站页面打开速度慢的几种情况

导致网站页面打开速度慢的原因有很多,主要注意以下几个方面,就能做到很好的避免。...

浏览器变慢有救了!只要2秒,重回新安装一样爽快!

而最近有小伙伴在后台留言,说自己电脑浏览器用久了后,速度变得越来越慢了。特别是用久后,每次打开浏览器加载半天,经常白屏卡上那么一小会,体验上要比看这loging在转还难受,差点以为死机了。其...

导致网站打开慢的原因以及解决方法

是什么原因会导致网站打开慢?又有什么办法解决呢?一般来说,http请求过多、网页过大、服务器性能过差等等都可能导致网站打开慢。www.xy3000.com小蚁云安全乔妹为您分享一些参考解决方法:研究表...

还在为打开网页慢而苦恼吗?试试这招

不知道大家有没有这种感觉,家里网速明明很快,有20M,50M甚至100M,但不知道为什么打开网页,浏览页面的时候总感觉加载速度很慢。其实上网速度的快慢不仅仅取决于你家的宽带速度,也跟你的电脑硬件,系...

取消回复欢迎 发表评论: