所属板块:2. 执行上下文与闭包(JS 的核心引擎)
记录日期:2026-03-xx
更新:遇到 this 指向相关输出题或手写题时补充
1. this 的本质:执行上下文里的特殊属性
this 不是变量,而是执行上下文在创建阶段绑定的一个属性。
它的指向在函数被调用时才最终确定(与 [2-2] 里作用域的“定义时确定”完全相反)。
记住一句话:this 的值取决于函数是怎么被调用的,而不是函数写在哪里。
2. this 的五大绑定规则(按优先级从高到低)
-
new 绑定(最高优先级)
使用 new 调用构造函数时,this 指向新创建的对象function Person() { this.name = "张三"; } const p = new Person(); // this → p -
显式绑定(call / apply / bind)
强行指定 this- call/apply:立即执行
- bind:返回新函数,this 被永久绑定
function say() { console.log(this.name); } const obj = { name: "李四" }; say.call(obj); // "李四" -
隐式绑定(对象方法调用)
函数作为对象属性被调用时,this 指向该对象const obj = { name: "王五", say() { console.log(this.name); } }; obj.say(); // "王五" -
默认绑定(独立函数调用)
- 非严格模式:this → window / global
- 严格模式:this → undefined
function test() { console.log(this); } test(); // 非严格模式下是 window -
箭头函数的词法 this(特殊规则,不参与优先级竞争)
箭头函数没有自己的 this,它会继承外层作用域的 this(定义时确定)const obj = { name: "赵六", say: () => { console.log(this.name); } // this → window(不是 obj) }; obj.say();
3. 最常见的“隐式丢失”陷阱(面试高频)
把对象方法提取出来单独调用,this 就会丢失:
const obj = { name: "孙七", say() { console.log(this.name); } };
const fn = obj.say;
fn(); // undefined(this 变成 window 或 undefined)
// 回调函数也一样
setTimeout(obj.say, 0); // this 丢失
解决办法:用 bind、箭头函数、或包裹一层函数。
4. 优先级对决 & 手写实现(面试必考)
优先级顺序:new > 显式 > 隐式 > 默认
箭头函数直接跳过所有规则,找外层 this。
手写 call(简化版,面试够用):
Function.prototype.myCall = function(thisArg, ...args) {
const fn = this; // this 就是被调用的函数
thisArg = thisArg ?? window; // 非严格模式默认 window
const key = Symbol(); // 防止覆盖原有属性
thisArg[key] = fn;
const result = thisArg[key](...args);
delete thisArg[key];
return result;
};
// 使用示例
function say(age) { console.log(this.name, age); }
const obj = { name: "周八" };
say.myCall(obj, 18); // "周八 18"
(apply 和 bind 的手写版同理,bind 需要返回新函数并处理 new 调用)
5. 小结 & 复习时的“引擎视角”
- 遇到 this 题,先问:函数是怎么被调用的?
- 画出调用现场 → 套五大规则 → 看是否有箭头函数或隐式丢失
- [2-1] 的执行上下文创建阶段 + [2-2] 的作用域链 + 本文的 this,共同构成了闭包的完整底层逻辑
下一篇文章会进入 [2-4] 闭包(闭包的严格定义、底层原理、经典应用与内存泄漏处理)——这是整个板块的终极形态。
返回总目录:戳这里