
1.bind方法注意事项调用 f.bind(someObject) 会创建一个新函数这个新函数具有与f相同的函数体和作用域但this的值永久绑定到bind的第一个参数无论函数如何被调用。function f() { return this.a; } const g f.bind({ a: azerty }); console.log(g()); // azerty const h g.bind({ a: yoo }); // bind 只能生效一次 console.log(h()); // azerty const o { a: 37, f, g, h }; console.log(o.a, o.f(), o.g(), o.h()); // 37 37 azerty azerty2.关于箭头函数this函数是作为箭头函数的形式创建的所以它的this永久地绑定到其执行上下文中的thisconst obj { getThisGetter() { const getter () this; return getter; }, }; const fn obj.getThisGetter(); console.log(fn() obj); // true这个例子意思是getter里的this永远指向的是其执行上下文getThisGetter的this就是obj由于类体具有this上下文因此作为类字段的箭头函数会关闭类的this上下文箭头函数体中的this将正确指向实例对于静态字段来说是类本身。但是由于它是一个闭包而不是函数本身的绑定因此this的值不会根据执行上下文而改变。class C { a 1; autoBoundMethod () { console.log(this.a); }; test(){ console.log(this.a) } } const c new C(); c.autoBoundMethod(); // 1 const { autoBoundMethod } c; autoBoundMethod(); // 1 c.test() // 1// 如果调用类的普通函数此时应该是 undefined,因为class类是严格模式function a () { var a 9; return function b() { var b4; return () {console.log(this)} } } a()()();// window或严格模式下的undefined这里箭头函数this指向的是函数b的thisconst obj { name: 1, a: { name: 2, foo: function() { console.log(this); // 这里的 this 是 obj.a }, too: () console.log(this) // 这里的 this 是全局对象window 或 undefined } }; obj.a.foo(); // this指向的是obj.a obj.a.too(); // 输出全局对象或 undefined严格模式下 这里的too的this指向的obj的上下文为全局 注意 箭头函数的的上下文是属性和方法时候this指向是不同的 上下文是普通函数时候指向取决于函数的调用 上下文为属性时候this指向obj所坐在的作用域为全局作用域const obj { name: 1, a: { name: 2, foo: function() { console.log(this); // 这里的 this 是 obj.a }, too: () console.log(this), // 这里的 this 是全局对象window 或 undefined roo() { const test () {console.log(this)}; return test; } } }; const roo obj.a.roo; roo()(); //指向window const roo obj.a.roo(); roo(); //指向obj.a;总结普通函数 的this是调用时决定的谁调用就指向谁。箭头函数 的this是定义时决定的继承外层作用域的this。const obj { name: Obj, init: function() { console.log(1. init this:, this.name); // 场景 A: bind 返回的新函数 const boundFn (function() { console.log(2. inner regular this:, this.name); }).bind(this); // 场景 B: 箭头函数 const arrowFn () { console.log(3. arrow this:, this.name); }; return { boundFn, arrowFn, // 场景 C: 普通方法 normalMethod: function() { console.log(4. normal method this:, this.name); } }; } }; // 第一步获取内部对象 const internalObj obj.init(); // 第二步分别调用 internalObj.boundFn(); internalObj.arrowFn(); internalObj.normalMethod(); // 第三步高阶陷阱 - new 与 bind/arrow 的对抗 const NewBound new internalObj.boundFn(); const NewArrow new internalObj.arrowFn(); // 注意这行代码是否合法 1. init this: Obj 2. inner regular this: Obj 3. arrow this: Obj 4. normal method this: undefined (或者报错取决于 strict mode通常面试题默认非严格或模块外为 undefined/window) // 修正在现代模块环境或严格模式下normalMethod 独立调用时 this 为 undefined访问 undefined.name 会报错 TypeError。 // 但如果是浏览器非严格模式全局调用this 指向 window输出 window.name (通常为空字符串)。 // 为了严谨我们假设在标准 ES Module 或严格模式下 // 4. normal method this: 报错 (Cannot read properties of undefined) // 但如果题目隐含是在浏览器控制台直接运行且非严格 // 4. normal method this: (空字符串因为 window.name 默认为空) // 关于 new 的部分 // NewBound 执行时 // 2. inner regular this: Obj (bind 绑定的 this 在 new 调用时依然有效吗见下文解析) // NewArrow 执行时 // 报错: internalObj.arrowFn is not a constructor这是一道结合了 new绑定优先级、bind的不可变性、箭头函数词法作用域以及执行上下文的高级综合面试题。这道题能全面考察候选人对 JavaScriptthis机制底层逻辑的理解深度。New 最高Bind 次之隐式再次默认兜底。箭头无this看外层New 调 Bindthis失效。