CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
JavaScript 进阶/课时/函数与 this
RawBlame
课时目录12 节

JavaScript 进阶

  1. 01JS 进阶地图
  2. 02变量与提升
  3. 03运算符与相等
  4. 04控制流深入
  5. 05函数与 this
  6. 06异步深入
  7. 07对象与原型
  8. 08集合与 JSON
  9. 09模块系统
  10. 10内存与 GC
  11. 11调试与异常
  12. 12综合练习

函数与 this

this、bind/call/apply、闭包、IIFE、recursion。

35 分钟

函数与 this

javascript-core 讲过闭包入门;本课系统讲解 this 绑定规则、bind/call/apply、IIFE 与递归。React 类组件与 nodejs-essentials 事件回调里,this 丢失是经典 bug 来源。

学习目标

  • 说出 this 的四种绑定规则(默认、隐式、显式、new)
  • 使用 bind/call/apply 固定 this
  • 理解闭包在模块模式与递归中的应用

this 绑定规则

// 1. 默认绑定(非 strict 下指向 global/window)
function show() {
  console.log(this);
}
show();

// 2. 隐式绑定:obj.method() 中 this 指向 obj
const page = {
  title: '首页',
  getTitle() { return this.title; },
};
page.getTitle(); // '首页'

// 3. 显式绑定
show.call({ id: 1 });
show.apply({ id: 2 });

// 4. new 绑定
function User(name) {
  this.name = name;
}
const u = new User('Lee');

丢失 this 的经典场景

const page = {
  title: '首页',
  getTitle() { return this.title; },
};
const fn = page.getTitle;
fn(); // undefined(独立调用,默认绑定)

// 修复
const bound = page.getTitle.bind(page);
bound(); // '首页'

React 类组件曾需 this.handleClick = this.handleClick.bind(this);函数组件 + 箭头回调已规避多数场景。

bind / call / apply

function greet(greeting, punct) {
  return `${greeting}, ${this.name}${punct}`;
}
const person = { name: 'Lee' };

greet.call(person, '你好', '!');   // '你好, Lee!'
greet.apply(person, ['Hi', '.']);   // 'Hi, Lee.'

const hi = greet.bind(person, '你好');
hi('~'); // '你好, Lee~'

apply 适合参数已是数组;bind 返回新函数,适合事件监听。

箭头函数与 this

const timer = {
  seconds: 0,
  start() {
    setInterval(() => {
      this.seconds++; // 箭头函数不绑定自己的 this,继承 start 的 this
    }, 1000);
  },
};

箭头函数不能用作构造函数,也没有 arguments 对象。

IIFE 与模块模式

const counter = (function () {
  let n = 0;
  return {
    inc() { return ++n; },
    get() { return n; },
  };
})();
counter.inc(); // 1

IIFE 创建私有作用域,现代项目多用 ESM 替代。

递归

function flatten(arr) {
  return arr.reduce((acc, item) => {
    return acc.concat(Array.isArray(item) ? flatten(item) : item);
  }, []);
}
flatten([1, [2, [3]]]); // [1, 2, 3]

注意栈溢出:深递归可改迭代或尾调用优化(引擎支持有限)。

练习

  • 写对象方法赋值给变量后 this 丢失的 demo,用 bind 修复
  • 用 call 求数组 [1,2,3] 的 Math.max
  • 用闭包实现只允许调用一次的 once(fn)

小结

this 由调用方式决定;bind 固定上下文;箭头函数继承外层 this。 下一课异步深入。

加载本节练习…
← 上一课控制流深入下一课 →异步深入