this 输出题

"this 绑定 " 是前端面试最常考的 JavaScript 核心机制之一。

出题方式通常是 ------ 给一段带有函数 / 对象 / 箭头函数 / call / bind 的代码,让你说出输出结果并解释。


🌟 一、基础题:全局 this

js 复制代码
function foo() {
  console.log(this);
}
foo();

✅ 输出:

在浏览器中:window

在 Node.js 中:undefined(因为模块是严格模式)

🧠 解析:

普通函数调用,this 默认指向 全局对象(非严格模式)

严格模式下为 undefined


🌟 二、对象方法调用

js 复制代码
var name = 'window';
const obj = {
  name: 'obj',
  getName() {
    console.log(this.name);
  }
};
obj.getName();

✅ 输出:

复制代码
obj

🧠 解析:

getName 被作为对象方法调用,this 指向调用它的对象 ------ obj


🌟 三、丢失 this(最常考陷阱)

js 复制代码
var name = 'window';
const obj = {
  name: 'obj',
  getName() {
    console.log(this.name);
  }
};
const fn = obj.getName;
fn();

✅ 输出:

复制代码
window

🧠 解析:

fn 是普通函数引用调用,不再与 obj 绑定;

所以 this 回到默认绑定 ------ window(或严格模式下为 undefined)。

💡 面试加分点:

可以通过 fn.bind(obj) 修正 this。


🌟 四、箭头函数不绑定 this

js 复制代码
var name = 'window';
const obj = {
  name: 'obj',
  getName: () => {
    console.log(this.name);
  }
};
obj.getName();

✅ 输出:

复制代码
window

🧠 解析:

箭头函数没有自己的 this

它的 this 来自定义时的词法环境(此处是全局作用域)。


🌟 五、嵌套箭头函数捕获外层 this

js 复制代码
var name = 'window';
const obj = {
  name: 'obj',
  getName() {
    return () => console.log(this.name);
  }
};
const fn = obj.getName();
fn();

✅ 输出:

复制代码
obj

🧠 解析:

  • getName() 是普通方法调用,this 指向 obj
  • 箭头函数捕获定义时的 this(即 obj);
  • 所以最终输出 'obj'

🌟 六、call / apply / bind 显式绑定

js 复制代码
function foo() {
  console.log(this.name);
}
const obj = { name: 'obj' };

foo.call(obj);
foo.apply(obj);
const bar = foo.bind(obj);
bar();

✅ 输出:

复制代码
obj
obj
obj

🧠 解析:

callapplybind 都能显式绑定 this。


🌟 七、bind 后再 call(加分题)

js 复制代码
function foo() {
  console.log(this.name);
}
const obj1 = { name: 'obj1' };
const obj2 = { name: 'obj2' };

const fn = foo.bind(obj1);
fn.call(obj2);

✅ 输出:

复制代码
obj1

🧠 解析:

bind 一旦绑定 this,之后无论怎么调用,都不会被改变。
bind 的 this 绑定优先级最高。


🌟 八、构造函数中的 this

js 复制代码
function Foo(name) {
  this.name = name;
}
const a = new Foo('A');
const b = new Foo('B');
console.log(a.name, b.name);

✅ 输出:

复制代码
A B

🧠 解析:

  • 使用 new 调用函数时:

    1. 创建一个新对象;
    2. 绑定 this 到这个新对象;
    3. 执行函数体;
    4. 返回新对象(除非显式返回对象)。

🌟 九、new 与 bind 一起用(必问陷阱)

js 复制代码
function Foo(name) {
  this.name = name;
}
const obj = { name: 'obj' };
const Bar = Foo.bind(obj);
const b = new Bar('B');
console.log(b.name);
console.log(obj.name);

✅ 输出:

复制代码
B
obj

🧠 解析:

当函数通过 new 调用时,this 指向新创建的实例对象,

即使函数被 bind 绑定过,也会被 new 覆盖。

因此:

  • bname'B'
  • obj 不受影响。

🌟 十、隐式丢失(链式调用陷阱)

js 复制代码
var name = 'window';
const obj1 = {
  name: 'obj1',
  foo() {
    console.log(this.name);
  }
};
const obj2 = { name: 'obj2', foo: obj1.foo };
const fn = obj1.foo;

obj1.foo(); // ?
obj2.foo(); // ?
fn();       // ?

✅ 输出:

复制代码
obj1
obj2
window

🧠 解析:

  • obj1.foo() → 调用者是 obj1 → this = obj1
  • obj2.foo() → 调用者是 obj2 → this = obj2
  • fn() → 普通函数调用 → this = window

🎯 this 绑定优先级总结(面试口诀)

new 绑定 > 显式绑定(bind/call/apply) > 隐式绑定(obj.foo()) > 默认绑定(window 或 undefined)


🧠 面试建议:

面试官问 "this 输出什么" 时,

你可以快速按这个思路走:

1️⃣ 看调用方式 (普通 / 对象调用 / 构造 / 箭头)

2️⃣ 判断 this 来源 (隐式 / 显式 / 词法捕获)

3️⃣ 考虑优先级(new > bind > call > 隐式 > 默认)

相关推荐
冬奇Lab29 分钟前
一天一个开源项目(第200篇):next-forge - 生产级 Next.js SaaS 启动模板
前端·前端框架·开源
Profile排查笔记1 小时前
指纹浏览器怎么设置 IP?代理配置、检测与排错流程
前端·人工智能·后端·自动化
lzhdim1 小时前
13、JavaScript事件循环机制 - JavaScript学习系列文章
开发语言·前端·javascript·学习·ecmascript
liangshanbo12151 小时前
Vue 3 <script setup> 的本质原理是什么?它与普通 setup()有何区别?
前端·javascript·vue.js
IT_陈寒2 小时前
SpringBoot自动配置失效?你可能漏了这个小开关
前端·人工智能·后端
kyriewen2 小时前
我写了1个复盘Skill,和AI协作踩过的坑第二天自动变成护栏
前端·程序员·ai编程
风骏时光牛马2 小时前
AI提示词异常故障复盘分析
前端
SoaringHeart2 小时前
Flutter 进阶:NCanvasImageLoader 让 Canvas 也能画网络图
前端·flutter
计算机魔术师3 小时前
英伟达两个月叫停360亿美元生意:芯片巨头怕了反垄断?
前端
创新技术阁3 小时前
FastapiAdmin 前后端启动全流程详解
前端·后端·fastapi