JavaScript高级③|this指向详解,5种绑定规则彻底搞懂
author: 专注前端开发分享JavaScript干货title: JavaScript高级③this指向详解5种绑定规则彻底搞懂update: 2026-04-28tags: 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会丢失constfnobj.sayHi;fn();// undefinedthis指向全局/undefined// 常见场景回调函数setTimeout(obj.sayHi,1000);// undefined隐式丢失三、显式绑定call / apply / bindfunctiongreet(greeting,punctuation){console.log(${greeting}${this.name}${punctuation});}constperson{name:张三};// call立即调用参数逐个传greet.call(person,你好,);// 你好张三// apply立即调用参数用数组传greet.apply(person,[嗨,]);// 嗨张三// bind返回新函数不立即调用constboundGreetgreet.bind(person,早上好);boundGreet(。);// 早上好张三。四、new绑定构造函数调用functionPerson(name){// new调用时this指向新创建的对象this.namename;this.sayHifunction(){console.log(我是${this.name});};}constpnewPerson(张三);p.sayHi();// 我是张三this指向p// new做了什么// 1. 创建一个空对象 {}// 2. 将对象的 __proto__ 指向构造函数的 prototype// 3. 将构造函数中的 this 指向这个对象// 4. 执行构造函数代码// 5. 如果构造函数没有返回对象则返回这个新对象五、箭头函数没有自己的thisconstobj{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绑定优先级最高constboundFoofoo.bind(obj1);// 显式绑定constinstancenewboundFoo();// new绑定this指向新实例console.log(instance);// foo {} 不是obj1七、实战修正this指向// 场景1定时器中的thisconstobj{count:0,start(){// ❌ setTimeout的回调是独立调用this指向全局setTimeout(function(){this.count;console.log(this.count);// NaNthis指向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指向外层作用域这里可能是Windowconsole.log(this);// Window ❌});八、知识卡规则说明默认绑定独立调用this指向全局/undefined隐式绑定对象方法调用this指向对象显式绑定call/apply/bind手动指定thisnew绑定构造函数调用this指向新对象箭头函数没有this继承外层作用域的this九、课后作业分析下面代码输出并解释constobj{name:test,foo(){console.log(this.name);}};constfnobj.foo;fn();用三种方式实现在setTimeout回调中正确访问obj的name实现一个call的模拟函数myCall(fn, context, ...args)有问题欢迎评论区留言大家一起讨论标签JavaScript | this | call | apply | bind | 箭头函数 | this绑定 | 前端进阶