面试题答案
一键面试JavaScript严格模式下this绑定的不同陷阱
- 全局作用域下的this
- 非严格模式:在全局作用域中,
this
指向全局对象(浏览器中是window
)。
console.log(this === window); // true function globalFunction() { console.log(this === window); // true } globalFunction();
- 严格模式:在严格模式的全局作用域中,
this
是undefined
。
'use strict'; console.log(this === undefined); // true function globalFunction() { 'use strict'; console.log(this === undefined); // true } globalFunction();
- 非严格模式:在全局作用域中,
- 函数调用中的this
- 非严格模式:当函数作为普通函数调用时,
this
指向全局对象。
function normalFunction() { console.log(this === window); // true } normalFunction();
- 严格模式:当函数在严格模式下作为普通函数调用时,
this
是undefined
。
'use strict'; function normalFunction() { console.log(this === undefined); // true } normalFunction();
- 非严格模式:当函数作为普通函数调用时,
- 对象方法调用中的this
- 非严格模式与严格模式:对象方法调用时,
this
通常指向调用该方法的对象,这点在两种模式下基本一致。
const obj = { value: 42, method: function() { console.log(this.value); } }; obj.method(); // 42 'use strict'; const obj2 = { value: 42, method: function() { console.log(this.value); } }; obj2.method(); // 42
- 非严格模式与严格模式:对象方法调用时,
在复杂函数嵌套和对象方法调用场景中正确处理this绑定
- 复杂函数嵌套场景
- 问题:在对象方法内部的嵌套函数中,
this
指向可能并非预期。
const outerObj = { value: 42, outerMethod: function() { function innerFunction() { console.log(this); // 在非严格模式下指向全局对象,严格模式下为 undefined } innerFunction(); } }; outerObj.outerMethod();
- 解决方法
- 使用
that
变量:在外部函数中保存this
。
const outerObj = { value: 42, outerMethod: function() { const that = this; function innerFunction() { console.log(that.value); // 42 } innerFunction(); } }; outerObj.outerMethod();
- 使用箭头函数:箭头函数没有自己的
this
,它的this
继承自外层作用域。
const outerObj = { value: 42, outerMethod: function() { const innerFunction = () => { console.log(this.value); // 42 }; innerFunction(); } }; outerObj.outerMethod();
- 使用
- 问题:在对象方法内部的嵌套函数中,
- 对象方法调用场景
- 问题:当对象方法作为回调函数传递时,
this
指向可能改变。
const obj = { value: 42, method: function() { console.log(this.value); } }; const callback = obj.method; callback(); // 在非严格模式下 this 指向全局对象,严格模式下为 undefined,会报错
- 解决方法
- 使用
bind
方法:
const obj = { value: 42, method: function() { console.log(this.value); } }; const callback = obj.method.bind(obj); callback(); // 42
- 使用箭头函数:将对象方法定义为箭头函数,使其
this
继承外层作用域。
const obj = { value: 42, method: () => { console.log(this.value); // 这里的 this 取决于外层作用域,可能需要调整逻辑 } }; ``` 但要注意,箭头函数没有自己的 `this`,如果外层作用域不是预期的对象,可能会导致问题。一般在需要明确绑定到对象自身时,`bind` 方法更可靠。
- 使用
- 问题:当对象方法作为回调函数传递时,