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

相关推荐
七号练习生.c16 小时前
JQuery&Ajax
前端·ajax·jquery
FinClip16 小时前
AI时代,金融科技如何落地“对话就能办业务”?
前端
七号练习生.c16 小时前
结合Html、Javascript、Jquery做个简易的时间显示器
javascript·html·jquery
YianNib16 小时前
状态机是什么?
javascript
数学分析分析什么?16 小时前
微前端之qiankun+vue3简易示例
前端·微前端·qiankun
西洼工作室17 小时前
前端项目目录结构全解析
前端·vue.js
咫尺的梦想00717 小时前
vue的生命周期
前端·javascript·vue.js
一口甜西瓜17 小时前
nuxt2.x部署到linux
前端·nuxt.js
Data_Adventure17 小时前
从 TypeScript 到 Java(2):从脚本执行到 main 方法 —— 理解 Java 的程序入口
前端·后端
Data_Adventure17 小时前
从 TypeScript 到 Java(1):理解类与包结构
前端·后端