JavaScript中的this关键字

📅 2026/7/14 20:50:49
JavaScript中的this关键字
作为前端开发者,this关键字绝对是让人又爱又恨的存在.今天我们就来彻底搞懂它.一、this到底是什么简单来说,this是JavaScript中的一个特殊关键字, 它指向当前执行代码的上下文对象. 但具体指向谁, 得看它是怎么被调用的, 来看个示例:console.log(this);//在浏览器中输出window对象这里有个重要概念:this的指向不是在函数定义时确定的, 而是在函数被调用时确定的.这点和很多其他语言不同, 也是容易混淆的地方.二、this的四大绑定规则1) 默认绑定当函数独立调用时(不作为对象方法, 不通过call/apply/bind,也不是构造函数),this在非严格模式下指向全局对象(浏览器中是window),严格模式下是undefined.functionshowThis() {console.log(this);}showThis();//浏览器中输出 window(非严格模式)// 严格模式functionstrictShowThis() {use strict;console.log(this);}strictShowThis();//undefined2) 隐式绑定(方法调用)当函数作为对象的方法被调用时,this指向调用该方法的对象.const person {name:小明,sayHi:function() {console.log(你好,我是${this.name});}};person.sayHi();//输出 你好,我是小明 - this指向person对象隐式丢失问题:当方法被赋值给变量后调用, 会丢失原来的this绑定.const sayHi person.sayHi;sayHi();//输出 你好我是undefined-this指向全局对象或undefined3) 显示绑定我们可以强制指定函数调用时的this值, 这就是显式绑定. 使用call, apply, bind函数, 我们来看个示例:functionintroduce(lang, hobby) {console.log(我是${this.name}我会${lang}喜欢${hobby});}const person1 {name:张三 };const person2 {name:李四 };//call接受参数列表introduce.call(person1,JavaScript,打篮球);//输出 我是张三我会JavaScript喜欢打篮球//apply接受参数数组introduce.apply(person2, [Python,游泳]);//输出 我是李四我会Python喜欢游泳bind会创建一个新函数, 永久绑定this值:const person3 {name:王五 };const boundIntroduce introduce.bind(person3,Java,跑步);boundIntroduce();// 输出 我是王五我会Java喜欢跑步4) new绑定使用new调用函数(构造函数)时,this指向新创建的对象.functionPerson(name) {this.name name;this.sayName function() {console.log(this.name);};}const jack newPerson(Jack);jack.sayName();// 输出 Jack三、箭头函数的this特性箭头函数没有自己的this,它会捕获所在上下文的this值, 作为自己的this值, 且一旦确定就无法改变(即使使用call/apply/bind).const obj {name:箭头函数示例,regularFunc:function() {console.log(this.name);//this指向obj},arrowFunc:() {console.log(this.name);//this指向外层作用域(这里是window或undefined)}};obj.regularFunc();//输出 箭头函数示例obj.arrowFunc();//输出 undefined(严格模式)或空字符串(非严格模式)再看一个示例:functionTimer() {this.seconds 0;// 传统函数写法会有this问题setInterval(function() {this.seconds;// 这里的this指向window/undefinedconsole.log(this.seconds);},1000);// 箭头函数写法正确setInterval(() {this.seconds;// 这里的this指向Timer实例console.log(this.seconds);},1000);}const timer newTimer();四、特殊场景与实战应用1) DOM事件处理函数中的this:在DOM事件处理函数中,this指向触发事件的元素.document.getElementById(myBtn).addEventListener(click,function() {console.log(this);// 指向按钮元素});2) 定时器回调中的this:setTimeout(function() {console.log(this);//浏览器中指向window},1000);3) 立即执行函数中的this:(function() {console.log(this);//非严格模式指向window严格模式undefined})();4) 如何避免this的隐式丢失?//错误写法const obj {name:小明,sayHi:function() {setTimeout(function() {console.log(你好,我是${this.name});},100);}};obj.sayHi();//输出 你好,我是undefined// 解决方案1使用箭头函数const obj1 {name:小明,sayHi:function() {setTimeout(() {console.log(你好,我是${this.name});},100);}};// 解决方案2保存this引用const obj2 {name:小明,sayHi:function() {const self this;setTimeout(function() {console.log(你好,我是${self.name});},100);}};5) 多层对象调用时this的指向:const obj {name:外层,inner: {name:内层,sayName:function() {console.log(this.name);}}};obj.inner.sayName();// 输出 内层 - this指向直接调用者inner6) 类中的this:ES6类中的方法默认使用严格模式,this行为更符合预期:classPerson {constructor(name) {this.name name;}sayName() {console.log(this.name);}}const p newPerson(类示例);p.sayName();// 输出 类示例const say p.sayName;say();// 报错因为严格模式下this是undefined