面试必挂?JavaScript中this指向的6种场景全破解

4 阅读2分钟

为什么面试总考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做了四件事:

  1. 创建新对象

  2. this指向新对象

  3. 执行构造函数

  4. 返回新对象

四、强制指定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());

最后做一个简单记忆方法

  1. 函数调用时,看括号左边是谁

  2. new调用时,this是新对象

  3. 箭头函数用外面的this

  4. call/apply/bind直接指定

  5. 直接调用找window

只要掌握了上面的 this 指向的情况,this就算通关了!