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

相关推荐
风吹夏回15 小时前
TypeScript 快速上手指南:从 JavaScript 到类型安全
javascript·ubuntu·typescript
蜡台16 小时前
UniApp WebView 组件宽高设置与动态适配全方案
前端·javascript·uniapp·webview·iframe
半个烧饼不加肉16 小时前
JS 底层探究-- 调用栈(Call Stack)
开发语言·前端·javascript
子午16 小时前
基于DeepSeek的智能校园教务管理系统~Web管理系统+Vue3+Python+DeepSeek智能问答
前端
change_fate16 小时前
ERR_PNPM_WORKSPACE_PKG_NOT_FOUND In ...
java·服务器·前端
超人不会飞_Jay16 小时前
26.6.3Vue笔记
前端·vue.js·笔记
御坂1002716 小时前
Vue - @change应用实现下拉框联动功能
前端·javascript·vue.js
小雨下雨的雨16 小时前
基于 Electron 运行时的鸿蒙PC桌面应用-安全可靠的随机密码生成工具
前端·javascript·华为·electron·前端框架·鸿蒙
瘦瘦瘦大人17 小时前
Vue 项目实现关闭/刷新浏览器窗口前的离开确认提示
前端·javascript·vue.js
大家的林语冰17 小时前
尤雨溪官宣:Vite+ 全员加盟 Cloudflare,正式进军全栈开发和 AI 部署云平台!
前端·javascript·vite