news 2026/6/7 10:40:48

JavaScript高级③|this指向详解,5种绑定规则彻底搞懂

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript高级③|this指向详解,5种绑定规则彻底搞懂

author: 专注前端开发,分享JavaScript干货
title: JavaScript高级③|this指向详解,5种绑定规则彻底搞懂
update: 2026-04-28
tags: JavaScript,this,call,apply,bind,箭头函数,this绑定,前端进阶

作者:专注前端开发,分享JavaScript干货
更新时间:2026年4月
适合人群:有JS基础,经常被this指向搞晕的开发者


前言:this为什么难?

this不像传统语言指向当前类的实例,JS的this在函数调用时才确定

掌握5种绑定规则,就能100%判断this指向。


一、默认绑定(独立函数调用)

functionfoo(){console.log(this);}// 浏览器环境foo();// Window(非严格模式)// undefined(严格模式 'use strict')// Node.js环境foo();// global(非严格模式)// undefined(严格模式)

二、隐式绑定(作为对象方法调用)

constobj={name:"张三",sayHi(){console.log(this.name);}};obj.sayHi();// "张三"(this指向调用者obj)// ⚠️ 隐式丢失:把方法赋值给变量后,this会丢失constfn=obj.sayHi;fn();// undefined(this指向全局/undefined)// 常见场景:回调函数setTimeout(obj.sayHi,1000);// undefined(隐式丢失)

三、显式绑定(call / apply / bind)

functiongreet(greeting,punctuation){console.log(`${greeting}${this.name}${punctuation}`);}constperson={name:"张三"};// call:立即调用,参数逐个传greet.call(person,"你好","!");// "你好,张三!"// apply:立即调用,参数用数组传greet.apply(person,["嗨","~"]);// "嗨,张三~"// bind:返回新函数,不立即调用constboundGreet=greet.bind(person,"早上好");boundGreet("。");// "早上好,张三。"

四、new绑定(构造函数调用)

functionPerson(name){// new调用时,this指向新创建的对象this.name=name;this.sayHi=function(){console.log(`我是${this.name}`);};}constp=newPerson("张三");p.sayHi();// "我是张三"(this指向p)// new做了什么:// 1. 创建一个空对象 {}// 2. 将对象的 __proto__ 指向构造函数的 prototype// 3. 将构造函数中的 this 指向这个对象// 4. 执行构造函数代码// 5. 如果构造函数没有返回对象,则返回这个新对象

五、箭头函数(没有自己的this)

constobj={name:"张三",// 普通函数:this指向调用者sayHi1(){console.log(this.name);},// 箭头函数:this继承外层作用域sayHi2:()=>{console.log(this.name);// this指向外层(这里是全局)}};obj.sayHi1();// "张三" ✅obj.sayHi2();// undefined ❌// 箭头函数的经典场景:回调函数constobj2={name:"李四",items:[1,2,3],process(){// ❌ 普通函数:this指向有问题this.items.forEach(function(item){console.log(this.name,item);// undefined, 1...});// ✅ 箭头函数:this继承process的thisthis.items.forEach((item)=>{console.log(this.name,item);// "李四", 1...});}};obj2.process();

六、绑定优先级

new绑定 > 显式绑定(call/apply/bind)> 隐式绑定(对象方法)> 默认绑定
functionfoo(){console.log(this);}constobj1={name:"obj1",foo};constobj2={name:"obj2",foo};// 隐式绑定obj1.foo();// obj1// 显式绑定(优先级更高)obj1.foo.call(obj2);// obj2// new绑定(优先级最高)constboundFoo=foo.bind(obj1);// 显式绑定constinstance=newboundFoo();// new绑定,this指向新实例console.log(instance);// foo {} (不是obj1)

七、实战:修正this指向

// 场景1:定时器中的thisconstobj={count:0,start(){// ❌ setTimeout的回调是独立调用,this指向全局setTimeout(function(){this.count++;console.log(this.count);// NaN(this指向Window)},1000);// ✅ 方案1:用箭头函数setTimeout(()=>{this.count++;console.log(this.count);// 1, 2, 3...},1000);// ✅ 方案2:用bind绑定setTimeout(function(){this.count++;console.log(this.count);}.bind(this),1000);}};obj.start();// 场景2:事件处理函数button.addEventListener("click",function(){// this指向button元素console.log(this);// <button>});button.addEventListener("click",()=>{// this指向外层作用域(这里可能是Window)console.log(this);// Window ❌});

八、知识卡

规则说明
默认绑定独立调用,this指向全局/undefined
隐式绑定对象方法调用,this指向对象
显式绑定call/apply/bind,手动指定this
new绑定构造函数调用,this指向新对象
箭头函数没有this,继承外层作用域的this

九、课后作业

  1. 分析下面代码输出并解释:
    constobj={name:"test",foo(){console.log(this.name);}};constfn=obj.foo;fn();
  2. 用三种方式实现:在setTimeout回调中正确访问obj的name
  3. 实现一个call的模拟函数myCall(fn, context, ...args)

有问题欢迎评论区留言,大家一起讨论!


标签:JavaScript | this | call | apply | bind | 箭头函数 | this绑定 | 前端进阶

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

企业知识资产迁移革命:feishu-doc-export如何重构文档自动化生态

企业知识资产迁移革命&#xff1a;feishu-doc-export如何重构文档自动化生态 【免费下载链接】feishu-doc-export 飞书文档导出服务 项目地址: https://gitcode.com/gh_mirrors/fe/feishu-doc-export 当数字化转型浪潮席卷企业办公场景&#xff0c;知识资产的跨平台迁移…

作者头像 李华
网站建设 2026/6/7 10:31:40

Charles抓包保姆级教程:从下载安装到手机代理配置,一次搞定

Charles抓包实战指南&#xff1a;从零配置到移动端HTTPS解密第一次打开Charles时&#xff0c;那些密密麻麻的请求列表和复杂的代理设置确实容易让人望而生畏。作为移动端开发中最常用的抓包工具之一&#xff0c;Charles的价值远不止于简单的网络请求监控——它能让我们看清App与…

作者头像 李华
网站建设 2026/6/7 10:30:16

写论文的学术外挂!专业AI论文网站,逻辑清晰质量高

作为一名刚完成毕业论文的过来人&#xff0c;我太懂写论文的痛苦了 —— 选题迷茫、文献浩如烟海、框架混乱、逻辑不清、反复修改、查重降重让人抓狂... 直到我发现了这套 AI 论文写作工具组合&#xff0c;简直是论文写作的 "开挂神器"&#xff0c;效率直接拉满&…

作者头像 李华
网站建设 2026/6/7 10:30:07

遗传算法Python实战:N皇后问题的可调试实现

1. 这不是教科书&#xff0c;而是一次真实的遗传算法实战复盘 你打开这篇文章&#xff0c;大概率不是为了背诵“遗传算法是模拟生物进化过程的优化方法”这种定义。你可能刚在项目里卡在了一个组合爆炸问题上&#xff0c;试了暴力搜索跑不动&#xff0c;贪心算法总陷在局部最优…

作者头像 李华