如何理解JavaScript中的this关键字_JavaScript中this的指向如何确定
发布时间 - 2026-01-06 00:00:00 点击率:次JavaScript 中的 this 指向函数被调用时的执行上下文对象,而非定义时所在对象;普通调用时非严格模式下为全局对象(浏览器中为 window),严格模式下为 undefined;对象方法调用时 this 指向该对象;箭头函数无自有 this,继承外层非箭头函数的 this;new、call、apply、bind 可显式控制 this。
JavaScript 中的 this 不是指“函数定义时所在的对象”,而是“函数被调用时的执行上下文对象”——这个判断必须在每次调用时动态计算,不能靠代码位置猜。
普通函数调用时的 this 指向全局或 undefined
在非严格模式下,直接调用函数(如 foo()),this 指向全局对象(浏览器中是 window);严格模式下是 undefined。这是最容易误判的场景。
常见错误现象:this 在回调里突然变成 window 或 undefined,尤其在事件监听、定时器、数组方法(如 map、forEach)中传入普通函数时。
- 避免方式:用箭头函数(不绑定自己的
this)、显式绑定(bind/call/apply)、或改用对象方法调用形式 - 注意 Node.js 环境中全局对象是
global,不是window - ES Module 脚本默认启用严格模式,所以顶层普通函数调用的
this是undefined
对象方法调用决定 this 绑定到该对象
当函数作为对象属性被调用(如 obj.method()),this 指向 obj。但只看调用形式,不看函数如何定义或赋值。
const obj = {
name: 'Alice',
say() {
console.log(this.name)
; // 'Alice'
}
};
const fn = obj.say;
fn(); // this 是 undefined(严格模式),不是 obj!
obj.say(); // this 是 obj
关键点:
-
this只由「谁点出来的」决定,不是「谁定义的」 - 一旦把方法赋给变量(
fn = obj.say),就丢失了调用主体,变成普通调用 - 解构赋值也会触发相同问题:
const { say } = obj; say();同样丢失this
箭头函数没有自己的 this,继承外层作用域
箭头函数不创建自己的 this,它会沿作用域链向上查找最近的非箭头函数的 this 值。因此它无法通过 call、apply、bind 改变 this。
const obj = {
name: 'Bob',
regular() {
console.log(this.name); // 'Bob'
const arrow = () => console.log(this.name); // 'Bob'
arrow();
}
};
obj.regular();
适用场景:
- 避免在
setTimeout、Promise.then、addEventListener回调中手动bind(this) - 类中定义事件处理器时(
class X { handleClick = () => { ... } }) - 但不要在需要动态
this的地方用箭头函数,比如想让方法能被不同对象复用时
new 调用和 call/apply/bind 显式控制 this
new Fn() 会让 this 指向新创建的实例;Fn.call(obj, ...)、Fn.apply(obj, [...])、Fn.bind(obj) 则强制指定 this 值。
容易踩的坑:
-
bind返回的是新函数,必须调用才生效:obj.method.bind(other)(),漏掉末尾()就没执行 -
call和apply立即执行,区别只在参数传法:call用逗号分隔,apply用数组 - 箭头函数无法被
call/apply/bind修改this,传进去的值会被忽略
真正难的不是记住规则,而是意识到 this 的值永远取决于「函数怎么被调用」,而不是「函数怎么被写」。哪怕同一个函数,在不同调用形式下 this 可能完全不同。调试时别盯着函数体,先看调用表达式左侧是什么。
# javascript
# java
# js
# node.js
# node
# 处理器
# 浏览器
# app
# win
# 区别
# 作用域
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel模型关联查询教程_Laravel Eloquent一对多关联写法
进行网站优化必须要坚持的四大原则
韩国服务器如何优化跨境访问实现高效连接?
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
Android仿QQ列表左滑删除操作
如何在云指建站中生成FTP站点?
香港服务器WordPress建站指南:SEO优化与高效部署策略
如何快速打造个性化非模板自助建站?
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
Laravel观察者模式如何使用_Laravel Model Observer配置
浅谈Javascript中的Label语句
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
如何在宝塔面板中修改默认建站目录?
零基础网站服务器架设实战:轻量应用与域名解析配置指南
jquery插件bootstrapValidator表单验证详解
教学论文网站制作软件有哪些,写论文用什么软件
?
Laravel如何使用Blade组件和插槽?(Component代码示例)
如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
Laravel如何实现用户注册和登录?(Auth脚手架指南)
网站建设要注意的标准 促进网站用户好感度!
PHP 500报错的快速解决方法
Laravel如何创建自定义Facades?(详细步骤)
安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出
C语言设计一个闪闪的圣诞树
js代码实现下拉菜单【推荐】
EditPlus中的正则表达式 实战(2)
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
香港服务器租用每月最低只需15元?
php打包exe后无法访问网络共享_共享权限设置方法【教程】
如何快速生成专业多端适配建站电话?
js实现点击每个li节点,都弹出其文本值及修改
利用python获取某年中每个月的第一天和最后一天
Laravel如何生成和使用数据填充?(Seeder和Factory示例)
linux top下的 minerd 木马清除方法
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
如何快速搭建高效WAP手机网站吸引移动用户?
如何快速查询域名建站关键信息?
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
如何将凡科建站内容保存为本地文件?
深圳网站制作平台,深圳市做网站好的公司有哪些?
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
Laravel如何创建和注册中间件_Laravel中间件编写与应用流程
Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门
开心动漫网站制作软件下载,十分开心动画为何停播?
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
怎么用AI帮你为初创公司进行市场定位分析?
公司网站制作需要多少钱,找人做公司网站需要多少钱?
夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化


; // 'Alice'
}
};
const fn = obj.say;
fn(); // this 是 undefined(严格模式),不是 obj!
obj.say(); // this 是 obj