这是前端面试几乎必问的一组问题也是JavaScript this 机制的核心。一、this 到底是什么一句话this 不是函数定义时决定的而是函数调用时决定的。箭头函数除外例如functionfn(){console.log(this);}fn();// window浏览器非严格模式obj.fn();// objnewfn();// 新创建的对象fn.call(a);// a谁调用this 一般就指向谁。二、this 的绑定规则面试必答this 一共有5 种绑定方式。① 默认绑定普通函数直接调用。functionfn(){console.log(this);}fn();浏览器window严格模式undefined② 隐式绑定对象调用。constobj{name:Tom,say(){console.log(this.name);}};obj.say();输出Tom这里this obj因为obj.say()是 obj 调用了 say。隐式绑定丢失很多面试喜欢问。constobj{name:Tom,say(){console.log(this.name);}};constfnobj.say;fn();输出undefined因为fn();已经变成普通函数调用。③ 显式绑定call / apply / bind就是主动指定 this。例如functionfn(age){console.log(this.name,age);}constobj{name:Tom};fn.call(obj,20);输出Tom 20④ new 绑定functionPerson(name){this.namename;}constpnewPerson(Tom);console.log(p.name);new 做了四件事① 创建一个空对象 {} ② this 指向这个对象 ③ 执行函数 ④ 返回对象所以this p⑤ 箭头函数绑定特殊箭头函数没有自己的 this。它会继承外层作用域的 this。例如constobj{name:Tom,say(){constfn(){console.log(this.name);};fn();}};obj.say();输出Tom箭头函数里面没有 this它直接使用say()里的 this。三、call、apply、bind 的区别面试高频假设functionfn(a,b){console.log(this.name,a,b);}constobj{name:Tom};call立即执行。参数一个一个传。fn.call(obj,1,2);等价于this obj fn(1,2)输出Tom 1 2apply立即执行。参数必须放数组。fn.apply(obj,[1,2]);输出Tom 1 2bind不会立即执行。返回一个新函数。constnewFnfn.bind(obj);newFn(1,2);输出Tom 1 2所以方法是否立即执行参数形式返回值call✅一个一个传执行结果apply✅数组执行结果bind❌一个一个传新函数四、为什么箭头函数没有 this这是面试最喜欢问的一题。原因箭头函数的设计目标就是不创建自己的this。普通函数在调用时会创建自己的thisfunctionfn(){}执行时JavaScript 引擎会根据调用方式决定fn() obj.fn() new fn() call() apply()不同调用方式会生成不同的 this。而箭头函数constfn(){};没有自己的this、arguments、super和new.target。它在创建时就会从外层最近的非箭头函数或全局作用域词法捕获Lexical Thisthis之后永远不会改变。例如constobj{name:Tom,say(){constfn(){console.log(this.name);};fn();}};obj.say();执行过程say() 的 this → obj 箭头函数没有自己的 this 直接沿作用域链找到 say() 的 this 所以输出 obj.name五、为什么 call、apply、bind 对箭头函数无效因为箭头函数没有自己的thiscall、apply、bind只能修改普通函数的this无法覆盖箭头函数已经词法绑定的this。constobj1{name:Tom};constobj2{name:Jerry};constfn(){console.log(this.name);};fn.call(obj1);fn.apply(obj2);constnewFnfn.bind(obj1);newFn();三次输出都相同因为箭头函数始终使用创建时所在作用域的this。六、面试回答模板2 分钟JavaScript 中this通常是在函数调用时确定的而不是定义时确定。普通函数主要有默认绑定、隐式绑定、显式绑定call/apply/bind和new绑定四种规则。call和apply都会立即执行函数区别是参数传递方式不同bind不会立即执行而是返回一个绑定了this的新函数。箭头函数比较特殊它没有自己的this采用词法作用域在定义时继承外层作用域的this因此call、apply、bind都无法修改箭头函数的this。这是箭头函数特别适合回调函数和异步场景的重要原因。