MST

星途 面试题库

面试题:JavaScript严格模式下的this绑定陷阱与应对策略

阐述JavaScript严格模式下this绑定会出现哪些与非严格模式不同的陷阱?在复杂函数嵌套和对象方法调用场景中,如何正确处理this绑定以避免错误?请结合代码示例分析。
26.6万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

JavaScript严格模式下this绑定的不同陷阱

  1. 全局作用域下的this
    • 非严格模式:在全局作用域中,this 指向全局对象(浏览器中是 window)。
    console.log(this === window); // true
    function globalFunction() {
        console.log(this === window); // true
    }
    globalFunction();
    
    • 严格模式:在严格模式的全局作用域中,thisundefined
    'use strict';
    console.log(this === undefined); // true
    function globalFunction() {
        'use strict';
        console.log(this === undefined); // true
    }
    globalFunction();
    
  2. 函数调用中的this
    • 非严格模式:当函数作为普通函数调用时,this 指向全局对象。
    function normalFunction() {
        console.log(this === window); // true
    }
    normalFunction();
    
    • 严格模式:当函数在严格模式下作为普通函数调用时,thisundefined
    'use strict';
    function normalFunction() {
        console.log(this === undefined); // true
    }
    normalFunction();
    
  3. 对象方法调用中的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绑定

  1. 复杂函数嵌套场景
    • 问题:在对象方法内部的嵌套函数中,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();
      
  2. 对象方法调用场景
    • 问题:当对象方法作为回调函数传递时,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` 方法更可靠。