面试官:请解释一下 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个真实场景让你代码更优雅》

相关推荐
前端橙一陈40 分钟前
LocalStorage Token vs HttpOnly Cookie 认证方案
前端·spring boot
~无忧花开~43 分钟前
JavaScript学习笔记(十五):ES6模板字符串使用指南
开发语言·前端·javascript·vue.js·学习·es6·js
泰迪智能科技011 小时前
图书推荐丨Web数据可视化(ECharts 5)(微课版)
前端·信息可视化·echarts
CodeCraft Studio1 小时前
借助Aspose.Email,使用 Python 读取 Outlook MSG 文件
前端·python·outlook·aspose·email·msg·python读取msg文件
家里有只小肥猫3 小时前
react 初体验2
前端·react.js·前端框架
慧慧吖@3 小时前
前端发送请求时,参数的传递格式
前端
L李什么李3 小时前
HTML——使用表格制作简历
前端·javascript·html
未来之窗软件服务3 小时前
万象EXCEL开发(八)excel公式解析与依赖映射 ——东方仙盟金丹期
前端·excel·仙盟创梦ide·东方仙盟·万象excel
linuxxx1103 小时前
ajax() 回调函数参数详解
前端·ajax·okhttp
王嘉俊9253 小时前
ThinkPHP 入门:快速构建 PHP Web 应用的强大框架
开发语言·前端·后端·php·框架·thinkphp