JavaScript中this指向的速记方法 前言 JavaScript中的this指向是许多开发者容易混淆的概念,但掌握它对于编写高质量的JavaScript代码至关重要。本文将提供一套简单易记的规则,帮助你快速判断this的指向,并通过实例加深理解。
一、this指向的基本规则 1. 全局上下文中的this 在全局执行上下文中(非严格模式下),this指向全局对象:
1 2 3 4 5 console .log (this === window ); console .log (this === global );
速记口诀 :全局上下文,this指向全局对象。
2. 函数调用中的this 2.1 普通函数调用 1 2 3 4 5 function fn ( ) { console .log (this ); } fn ();
速记口诀 :普通函数调用,非严格模式指向全局,严格模式为undefined。
2.2 对象方法调用 1 2 3 4 5 6 7 8 const obj = { name : '张三' , sayName ( ) { console .log (this .name ); } }; obj.sayName ();
速记口诀 :对象方法调用,this指向调用该方法的对象。
2.3 构造函数调用 1 2 3 4 5 6 function Person (name ) { this .name = name; } const p = new Person ('李四' );console .log (p.name );
速记口诀 :构造函数调用,this指向新创建的实例对象。
2.4 call/apply/bind调用 1 2 3 4 5 6 7 8 9 function fn ( ) { console .log (this .name ); } const obj = { name : '王五' };fn.call (obj); fn.apply (obj); const boundFn = fn.bind (obj);boundFn ();
速记口诀 :call/apply/bind调用,this指向指定的第一个参数。
二、特殊情况与陷阱 1. 箭头函数中的this 箭头函数没有自己的this,它会捕获其所在上下文的this值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const obj = { name : '赵六' , regularFn ( ) { console .log (this .name ); const arrowFn = ( ) => { console .log (this .name ); }; arrowFn (); } }; obj.regularFn ();
速记口诀 :箭头函数没有自己的this,继承外层作用域的this。
2. 事件处理函数中的this 1 2 3 4 5 6 7 8 9 const btn = document .getElementById ('myBtn' );btn.addEventListener ('click' , function ( ) { console .log (this ); }); btn.addEventListener ('click' , () => { console .log (this ); });
速记口诀 :事件处理函数中,普通函数指向触发元素,箭头函数继承外层this。
3. 定时器中的this 1 2 3 4 5 6 7 8 9 10 11 12 13 14 const obj = { name : '钱七' , regularFn ( ) { setTimeout (function ( ) { console .log (this .name ); }, 100 ); setTimeout (() => { console .log (this .name ); }, 100 ); } }; obj.regularFn ();
速记口诀 :定时器回调中,普通函数指向全局,箭头函数继承外层this。
三、this指向判断流程图 1 2 3 4 5 6 7 8 9 10 graph TD A[开始判断this指向] --> B{是箭头函数吗?} B -->|是| C[继承外层作用域的this] B -->|否| D{是new调用吗?} D -->|是| E[指向新创建的实例] D -->|否| F{是call/apply/bind调用吗?} F -->|是| G[指向指定的第一个参数] F -->|否| H{是对象方法调用吗?} H -->|是| I[指向调用该方法的对象] H -->|否| J[指向全局对象或undefined]
四、实用技巧与解决方案 1. 保存this引用 在ES6之前,常用变量保存this引用:
1 2 3 4 5 6 7 8 9 const obj = { name : '孙八' , regularFn ( ) { const self = this ; setTimeout (function ( ) { console .log (self.name ); }, 100 ); } };
2. 使用箭头函数 ES6+推荐使用箭头函数:
1 2 3 4 5 6 7 8 const obj = { name : '周九' , regularFn ( ) { setTimeout (() => { console .log (this .name ); }, 100 ); } };
3. 使用bind方法 1 2 3 4 5 6 7 8 const obj = { name : '吴十' , regularFn ( ) { setTimeout (function ( ) { console .log (this .name ); }.bind (this ), 100 ); } };
五、常见面试题解析 1. 对象方法中的this 1 2 3 4 5 6 7 8 9 10 const obj = { name : '对象' , getName ( ) { return this .name ; }, getNameArrow : () => this .name }; console .log (obj.getName ()); console .log (obj.getNameArrow ());
2. 嵌套函数中的this 1 2 3 4 5 6 7 8 9 10 11 12 13 14 const obj = { name : '嵌套' , outer ( ) { console .log (this .name ); function inner ( ) { console .log (this .name ); } inner (); } }; obj.outer ();
3. 链式调用中的this 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const calculator = { value : 0 , add (num ) { this .value += num; return this ; }, multiply (num ) { this .value *= num; return this ; }, getResult ( ) { return this .value ; } }; const result = calculator.add (5 ).multiply (2 ).add (3 ).getResult ();
六、this指向速记表
调用方式
this指向
示例
全局上下文
全局对象
console.log(this)
普通函数调用
全局对象/undefined
fn()
对象方法调用
调用该方法的对象
obj.method()
构造函数调用
新创建的实例
new Constructor()
call/apply/bind
指定的第一个参数
fn.call(obj)
箭头函数
继承外层作用域的this
() => {}
DOM事件处理函数
触发事件的元素
element.onclick = function() {}
定时器回调
全局对象/继承外层this
setTimeout(fn, 100)
七、总结 掌握JavaScript中this的指向规则是每个前端开发者的必备技能。通过本文提供的速记方法和规则,你可以快速判断各种场景下this的指向:
全局上下文 :this指向全局对象
普通函数调用 :非严格模式指向全局,严格模式为undefined
对象方法调用 :this指向调用该方法的对象
构造函数调用 :this指向新创建的实例
call/apply/bind调用 :this指向指定的第一个参数
箭头函数 :没有自己的this,继承外层作用域的this