面试官:请解释一下 JS 的 this 指向。别慌,看完这篇让你对答如流!

大家好啊!我是大华! 经常面试的朋友应该知道,JavaScript中的this指向是一个非常经典的问题。很多朋友一听到this就头皮发麻。所以来整理了一下这篇文章。

先来个最简单粗暴的理解:this就是一个指向函数执行时所属对象的引用。就是:谁调用这个函数,this就指向谁。

我们看几个真实场景就明白了!

场景1:普通函数调用

javascript 复制代码
function sayHello() {
  console.log(this === window);
}

sayHello();  // 输出:true

这里直接调用sayHello,相当于window.sayHello(),所以this指向window。

但在严格模式下:

javascript 复制代码
"use strict";
function sayHello() {
  console.log(this);
}

sayHello();  // 输出:undefined

看,严格模式下this就是undefined,避免了指向全局对象的问题。

场景2:对象方法调用

javascript 复制代码
const person = {
  name: "小明",
  sayName: function() {
    console.log("我叫" + this.name);
  }
};

person.sayName();  // 输出:我叫小明

这里sayNameperson对象的方法,所以this指向person对象。

但是注意这个坑:

javascript 复制代码
const person = {
  name: "小明",
  sayName: function() {
    console.log("我叫" + this.name);
  }
};

const say = person.sayName;
say();  // 输出:我叫undefined

为什么?因为say()是直接调用的,this指向了window,而window没有name属性。

场景3:构造函数调用

javascript 复制代码
function Person(name) {
  this.name = name;
}

const xiaoming = new Person("小明");
console.log(xiaoming.name);  // 输出:小明

使用new操作符时,this指向新创建的对象实例。

场景4:箭头函数

这是ES6的新特性,也是面试常考点:

javascript 复制代码
const person = {
  name: "小明",
  hobbies: ["篮球", "游泳"],
  showHobbies: function() {
    this.hobbies.forEach(function(hobby) {
      console.log(this.name + "喜欢" + hobby);
    });
  }
};

person.showHobbies();  
// 输出:undefined喜欢篮球
// 输出:undefined喜欢游泳

为什么是undefined?因为forEach里的回调函数是独立调用的,this指向window。

用箭头函数解决:

javascript 复制代码
const person = {
  name: "小明",
  hobbies: ["篮球", "游泳"],
  showHobbies: function() {
    this.hobbies.forEach((hobby) => {
      console.log(this.name + "喜欢" + hobby);
    });
  }
};

person.showHobbies();  
// 输出:小明喜欢篮球
// 输出:小明喜欢游泳

箭头函数的this继承自外层作用域,所以这里指向person对象。

场景5:改变this指向

有时候我们需要手动改变this指向,JavaScript提供了3个方法:

call方法:

javascript 复制代码
function introduce(age, hobby) {
  console.log(`我是${this.name},今年${age}岁,喜欢${hobby}`);
}

const person = { name: "小明" };

introduce.call(person, 18, "篮球");
// 输出:我是小明,今年18岁,喜欢篮球

apply方法:

javascript 复制代码
function introduce(age, hobby) {
  console.log(`我是${this.name},今年${age}岁,喜欢${hobby}`);
}

const person = { name: "小明" };

introduce.apply(person, [18, "篮球"]);
// 输出:我是小明,今年18岁,喜欢篮球

bind方法:

javascript 复制代码
function introduce(age, hobby) {
  console.log(`我是${this.name},今年${age}岁,喜欢${hobby}`);
}

const person = { name: "小明" };
const introduceXiaoming = introduce.bind(person, 18);

introduceXiaoming("游泳");  
// 输出:我是小明,今年18岁,喜欢游泳

记住这个判断顺序,面试时超有用:

  1. 函数是否用new调用?是 → this指向新对象
  2. 是否用call/apply/bind指定this?是 → this指向指定对象
  3. 是否是箭头函数?是 → this继承外层作用域
  4. 是否是对象的方法?是 → this指向该对象
  5. 以上都不是 → this指向全局对象(严格模式下为undefined)

总结

this指向其实就一句话:看函数是怎么被调用的,而不是在哪里定义的。

记住几个关键点:

  • 普通函数调用:指向全局对象(或undefined)
  • 对象方法调用:指向该对象
  • 构造函数调用:指向新创建的实例
  • 箭头函数:继承外层作用域的this
  • 可以用call/apply/bind手动改变this指向

下次面试官再问this,你就可以自信地回答了!记得多写代码多练习,实践出真知哦~

希望这篇文章对你有帮助!如果有任何问题,欢迎留言讨论~

📌往期精彩

《写给小公司前端的 UI 规范:别让页面丑得自己都看不下去》

《只会写 Mapper 就敢说会 MyBatis?面试官:原理都没懂》

《别再手写判空了!SpringBoot 自带的 20 个高效工具类》

《别学23种了!Java项目中最常用的6个设计模式,附案例》

《Vue3+TS设计模式:5个真实场景让你代码更优雅》

相关推荐
超哥--1 小时前
B站视频内容智能分析系统(九):React 前端与管理面板
前端·react.js·前端框架
Cutecat_4 小时前
视频字幕处理工具横向:提取模式 vs 编辑模式,该如何选择
android·前端·ios·语音识别
dsyyyyy11014 小时前
JavaScript变量
开发语言·javascript·ecmascript
qq_422152574 小时前
PDF 加水印工具怎么选?2026 年文档版权保护方案对比
前端·pdf·github
kyriewen4 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
brucelee1865 小时前
OpenClaw 浏览器控制(Chrome MCP)完整教程
前端·chrome
ct9785 小时前
React 状态管理方案深度对比
开发语言·前端·react
胡志辉的博客6 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖6 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty6 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js