this 指向与 call / apply / bind
this 是函数运行时的“当前对象”,由调用方式决定:默认调用指向 window(严格模式下 undefined);方法调用指向调用者;构造函数指向新实例;箭头函数没有自己的 this,继承外层词法作用域。call / apply / bind 都是显式指定 this:call 与 apply 立即执行(参数逐个传 / 数组传),bind 返回一个永久绑定的函数。
面试常考“箭头函数能否 new”:不能,它没有 prototype 与 this 机制,new 会直接报错。另一个高频追问:bind 返回的函数再 call 改 this 无效 —— bind 的绑定是永久的(内部用 bind 后的函数已记录 this)。
- this 四规则:默认、隐式(方法调用)、显式(call/apply/bind)、new
- 箭头函数没有 this,继承定义时的外层作用域
- call / apply 立即执行,bind 返回新函数且绑定不可再改
JS
// 默认调用 function show() { console.log('this =', this === window ? 'window' : this); } show(); // window(非严格模式) // 方法调用:this 指向调用者 const obj = { name: '小明', say() { console.log(this.name); } }; obj.say(); // 小明 const fn = obj.say; fn(); // undefined(this 丢失) // call / apply / bind 显式指定 function greet(g, p) { console.log(g + ',' + this.name + ',' + p); } greet.call({ name: '小红' }, '你好', '吃了吗'); // 立即执行,逐个传参 greet.apply({ name: '小刚' }, ['嗨', '在吗']); // 立即执行,数组传参 const bound = greet.bind({ name: '小亮' }, '哈喽'); // 返回新函数 bound('干嘛呢'); // 箭头函数:this 继承外层,call 改不动 const arrow = { say: () => console.log('箭头 this 是全局:', this === window) }; arrow.say(); // true arrow.say.call({ name: 'X' }); // 仍然 true // 手写 call(面试常考) Function.prototype.myCall = function (ctx, ...args) { ctx = ctx == null ? window : Object(ctx); // 基本类型装箱 const key = Symbol(); // 唯一键防覆盖原属性 ctx[key] = this; const res = ctx[key](...args); delete ctx[key]; return res; }; greet.myCall({ name: '手写' }, '嘿', '不吃饭');
本节要点this 由调用方式决定;call / apply / bind 显式指定(bind 永久);箭头函数没有 this。




