news 2026/4/17 21:37:20

JavaScript 对 this 对象的理解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript 对 this 对象的理解

一、this的概念

this是执行上下文中的一个属性,它指向最后一个调用这个方法的对象。(这句话听着很拗口)

简单理解就是:谁调用了函数(或方法),this就指向谁。(就这样记就好)

至于“指向最后一个调用这个方法的对象”,可以通过举一个例子解释:

const a = { name: '11', b: { name: '22', c: { name: '33', fn: function () { console.log(this.name) }, } } } a.b.c.fn()

可以看到。这里a、b、c 看着好像都调用了 fn 函数,但是我们都知道,最后调用者是 c,所以这里的“指向最后一个调用这个方法的对象”,也就能通过这个例子感受到。

二、this的指向可以通过四种调用模式来判断

1. 函数调用模式:当一个函数不是一个对象的属性时,直接作为函数来调用时,this 指向全局对象。(补充 -> 函数定义:不依附于任何对象、可以被直接调用的代码块。)

// 1. 函数调用模式 function fn() { console.log(this) // this 指向全局 (this === window) } fn() // 这里本质上是:window.fn() 这样调用函数的

2. 方法调用模式:如果一个函数作为一个对象的方法来调用时,this指向这个对象。(补充 -> 方法定义:作为对象属性存在,并通过“对象.属性()”形式调用的函数。)

// 2. 方法调用模式 const obj = { fn: function () { console.log(this) } } obj.fn() // this 指向调用者 -> obj

3. 构造器调用模式:如果一个函数用 new 调用时,函数执行前会新创建一个对象,此时,this会指向这个新对象。

// 3. 构造器调用模式 function Person(name, age) { this.name = name this.age = age } // 不使用 new 的情况 // const p1 = Person('lxy', 18) // 如果不使用 new 的话,这里相当于函数调用模式,window.Person(),那么此时 this 指向全局 // console.log(p1) // undefined // console.log(name) // lxy -> window.name // console.log(age) // 18 -> window.age // 使用 new 的情况 const p2 = new Person('778', 18) // 如果使用 new 的话,这里会创建一个新的对象出来,此时 this 会指向这个新对象,也就是下面的 p2 console.log(p2) // {name: '778', age: 18} console.log(p2.name) // 778 console.log(p2.age) // 18

4. apply、call、bind调用模式,这三个函数都可以指定调用函数的 this 指向。

// 4. apply, call, bind 调用模式 function fn(x, y) { console.log(this) return x + y } const obj = { name: 'lxy' } const res1 = fn(1, 2) // 此时 this 为 window(全局) console.log(res1) // 3 const res2 = fn.apply(obj, [2, 3]) // 此时 this 为 obj console.log(res2) // 5 const res3 = fn.call(obj, 3, 4) // 此时 this 为 obj console.log(res3) // 7 const newFn = fn.bind(obj, 4, 5) // 调用 bind 得到一个新函数,该函数的 this 指向 obj const res4 = newFn() // 调用新函数 console.log(res4) // 9
其中apply方法接收两个参数:第一个是新 this 指向的对象,第二个是传递的参数(这里是数组等可迭代的对象)。apply 方法会直接调用函数。
call方法接收的参数:第一个是新 this 指向的对象,第二个是传递的参数(这里不是数组,这里的参数必须逐个列举出来)。call 方法会直接调用函数。
bind方法接收的参数:第一个是新 this 指向的对象,第二个参数是传递的参数,这里同样是要逐个列举出来。bind 方法会返回一个新的对象,该新对象的 this 指向参数一的对象,不会直接调用该函数。
注意:这个函数的 this 指向只能通过 new 来改变,其他的改变方式都不会生效。(看下面的代码)
function fn(name) { console.log(`我的名字是:${name}`) console.log(`我的年龄是:${this.age}`) } fn('lxy') // name -> lxy ; age -> undefined console.log('----------------------------------------') const obj = { age: 18 } const newFn = fn.bind(obj, 'lxy') newFn() // name -> lxy ; age -> 18 (此时 this 指向 obj,所以 age 有值) console.log('----------------------------------------') // 使用 apply 去改变 newFn 的 this 指向 newFn.apply({ age: 20 }, ['zzz']) // 这里仍然 name -> lxy ; age -> 18 并没有发生改变,说明 this 指向并没有发生改变 // 注意:这里会发现,为什么传入了 zzz 参数,但是 name 并没有发生改变,这是因为: // "在第一次使用 bind 的时候,lxy 这个参数已经固定了,它会作为函数的第一个参数。 // 后续调用时传入的参数会排在 bind 固定参数的后面。 // 由于函数只定义了一个参数 name,它只会取参数列表中的第一个,也就是 bind 固定的 'lxy'。" console.log('----------------------------------------') // 使用 call 去改变 newFn 的 this 指向 newFn.call({ age: 30 }, ['ccc']) // 这里与前者效果一样,this 未发生改变 console.log('----------------------------------------') // 使用 new 的方式去改变 newFn 的 this 指向 const a = new newFn('eee') // 可以发现 age -> undefined 说明 this 发生了改变,this 现在指向了 new 出来的新对象上去了,新对象上没有 age 所以显示为 undefined,name 仍然没有变,还是跟上面的一个道理

三、四种调用模式的优先级

这四种调用模式中,构造器调用模式优先级最高,然后是 apply、call、bind 调用模式,然后是 方法调用模式,最后是 函数调用模式。

构造器调用模式 > apply、call、bind调用模式 > 方法调用模式 > 函数调用模式

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 3:57:52

SP与CP并行策略实战:ms-swift中复杂拓扑结构的应用案例

SP与CP并行策略实战:ms-swift中复杂拓扑结构的应用案例 在千亿参数模型成为常态、多模态输入日益复杂的今天,训练系统的显存墙和通信瓶颈正以前所未有的速度逼近硬件极限。一个典型的场景是:某团队尝试用 Qwen3-VL 处理高分辨率图像与长文本混…

作者头像 李华
网站建设 2026/4/17 18:45:45

开源笔记管理工具:重新定义你的知识工作流

开源笔记管理工具:重新定义你的知识工作流 【免费下载链接】open-notebook An Open Source implementation of Notebook LM with more flexibility and features 项目地址: https://gitcode.com/GitHub_Trending/op/open-notebook 你是否曾经在浩瀚的信息海洋…

作者头像 李华
网站建设 2026/4/12 8:30:02

Next AI Draw.io 智能绘图工具完整使用教程

Next AI Draw.io 智能绘图工具完整使用教程 【免费下载链接】next-ai-draw-io 项目地址: https://gitcode.com/GitHub_Trending/ne/next-ai-draw-io 还在为绘制专业图表而烦恼吗?传统绘图工具需要你手动拖拽每个元素、调整每条连线、配置每种样式&#xff0…

作者头像 李华
网站建设 2026/4/14 15:14:31

工业现场数据采集系统:Keil5+STM32快速理解

工业现场数据采集实战:从Keil5STM32入门到工程落地你有没有遇到过这样的场景?在工厂车间里,几台老旧设备还在靠人工抄表记录温度、电流;PLC已经满负荷运行,无法接入新的传感器;而老板却要求“把所有数据传到…

作者头像 李华
网站建设 2026/4/16 17:02:38

终极智能RSS阅读器:用AI重新定义你的信息获取方式

终极智能RSS阅读器:用AI重新定义你的信息获取方式 【免费下载链接】feedme 实时聚合 Hacker News/Github Trending/Higging Face Daily Papers 等平台信息,AI 生成中文摘要 项目地址: https://gitcode.com/gh_mirrors/feedme1/feedme 在信息过载的…

作者头像 李华
网站建设 2026/4/14 4:27:41

ThinkPad X230黑苹果终极指南:从零开始的完整安装方案

ThinkPad X230黑苹果终极指南:从零开始的完整安装方案 【免费下载链接】X230-Hackintosh READMEs, OpenCore configurations, patches, and notes for the Thinkpad X230 Hackintosh 项目地址: https://gitcode.com/gh_mirrors/x2/X230-Hackintosh 想要让经典…

作者头像 李华