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 > 隐式 > 默认)

相关推荐
Dream it possible!3 小时前
LeetCode 面试经典 150_链表_合并两个有序链表(58_21_C++_简单)
leetcode·链表·面试·1024程序员节
yoke菜籽3 小时前
面试150——动态规划
1024程序员节
楊无好3 小时前
React中ref
前端·react.js
维他命Coco3 小时前
js常见开发学习
javascript
Dontla3 小时前
Tailwind CSS Next.js实战(官方)Tailwind Demo、Tailwind教程
1024程序员节
程琬清君3 小时前
vue3 confirm倒计时
前端·1024程序员节
麦麦大数据3 小时前
F033 vue+neo4j图书智能问答+知识图谱推荐系统 |知识图谱+neo4j+vue+flask+mysql实现代码
vue.js·flask·nlp·neo4j·智能问答·图书·1024程序员节
kaikai_sk3 小时前
达梦数据库sql笔记
1024程序员节
码以致用3 小时前
StarRocks笔记
数据库·starrocks·olap·1024程序员节