为什么面试总考this?JavaScript中的this关键字经常变化,让很多人困惑。超过70%的前端面试会问this指向的问题。这篇文章教你完全掌握this的6种情况,面试不再怕。一、全局环境中的this(最简单情况)情况说明:在全局或者普通函数中使用
console.log(this); // 浏览器中是window,Node.js中是global
function showThis() { console.log(this); // 结果同上}showThis();
关键点:非严格模式指向全局对象,严格模式是undefined二、对象方法中的this(容易出错)情况说明:作为对象的方法使用时
const user = { name: '小明', greet() { console.log(`你好,${this.name}`); }};
user.greet(); // 输出:你好,小明
出错情况:
const greet = user.greet;greet(); // 输出:你好,undefined(this指向错了)
解决方法:用bind固定this
const boundGreet = user.greet.bind(user);boundGreet(); // 正确输出
三、构造函数中的this(new关键字)情况说明:用new创建对象时
function Person(name) { this.name = name;}
const p = new Person('小红');console.log(p.name); // 输出:小红
原理:new做了四件事:
-
创建新对象
-
this指向新对象
-
执行构造函数
-
返回新对象
四、强制指定this(call/apply/bind)情况说明:用call、apply或bind方法指定this
function introduce(age, hobby) { console.log(`我是${this.name},${age}岁,喜欢${hobby}`);}
const person = { name: '张三' };
// call用法introduce.call(person, 25, '篮球');
// apply用法introduce.apply(person, [25, '篮球']);
// bind用法const boundIntro = introduce.bind(person);boundIntro(25, '篮球');
那么他们之间也是有区别的:
-
call:一个个传参数
-
apply:用数组传参数
-
bind:返回新函数
五、箭头函数中的this(特殊规则)情况说明:箭头函数没有自己的this,用外面的this;箭头函数没有自己的this,继承外层作用域
const obj = { value: 42, getValue: function() { // 普通函数 setTimeout(function() { console.log(this.value); // undefined(this指向window) }, 100);
// 箭头函数 setTimeout(() => { console.log(this.value); // 42(继承外层this) }, 100); }};
obj.getValue();
重要规则:箭头函数的this在定义时确定,不是调用时确定六、DOM事件中的this(实际应用)情况说明:在DOM事件处理函数中使用
<button id="myBtn">点击我</button>
<script> document.getElementById('myBtn').addEventListener('click', function() { console.log(this); // 指向被点击的按钮 });</script>
可能出现这样的情况:
class ButtonHandler { handleClick() { console.log(this); // 不是按钮元素! }}
const handler = new ButtonHandler();document.getElementById('myBtn').addEventListener('click', handler.handleClick);
这个时候,this 可不是这个按钮本身。解决方法:利用bind或者箭头函数
// 方法1:用binddocument.getElementById('myBtn').addEventListener('click', handler.handleClick.bind(handler));
// 方法2:用箭头函数document.getElementById('myBtn').addEventListener('click', () => handler.handleClick());
最后做一个简单记忆方法
-
函数调用时,看括号左边是谁
-
new调用时,this是新对象
-
箭头函数用外面的this
-
call/apply/bind直接指定
-
直接调用找window
只要掌握了上面的 this 指向的情况,this就算通关了!