MST

星途 面试题库

面试题:JavaScript严格模式对函数this指向的影响及应用场景

详细分析JavaScript严格模式下函数内部this指向的变化规律,结合实际应用场景,如模块开发、事件处理等,说明如何利用严格模式下this指向的特性来编写更健壮、可维护的代码,同时指出在这些场景中使用非严格模式可能带来的问题。
46.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

JavaScript严格模式下函数内部this指向变化规律

  1. 全局作用域:在严格模式下,全局作用域中的 this 不再指向全局对象(如浏览器中的 window),而是 undefined。例如:
'use strict';
console.log(this); // undefined
  1. 函数调用
    • 普通函数调用:在严格模式下,函数内部的 this 不会自动指向全局对象。如果函数不是作为对象的方法调用(即没有通过对象.方法() 的形式调用),this 将保持为 undefined。例如:
'use strict';
function test() {
    console.log(this);
}
test(); // undefined
  • 作为对象方法调用:当函数作为对象的方法被调用时,this 指向调用该方法的对象。例如:
'use strict';
const obj = {
    value: 42,
    printThis: function() {
        console.log(this.value);
    }
};
obj.printThis(); // 42
  1. 构造函数调用:在严格模式下,构造函数内部的 this 指向新创建的对象实例。例如:
'use strict';
function Person(name) {
    this.name = name;
}
const person = new Person('John');
console.log(person.name); // John
  1. 箭头函数:箭头函数没有自己的 this 绑定,它会捕获其所在上下文的 this 值。在严格模式下同样如此,箭头函数的 this 始终指向它定义时所在的作用域中的 this。例如:
'use strict';
const obj = {
    value: 42,
    getThis: () => {
        console.log(this);
    }
};
obj.getThis(); // undefined(因为箭头函数的this指向全局作用域,严格模式下全局作用域this为undefined)

实际应用场景及利用特性编写健壮可维护代码

  1. 模块开发
    • 在模块开发中,严格模式有助于避免意外的全局变量声明。例如,当在模块中定义函数时,严格模式下函数内部的 this 不会指向全局对象,这样可以防止无意中修改全局状态。假设我们有一个模块用于计算数学操作:
// mathModule.js
'use strict';
const mathOperations = {
    add: function(a, b) {
        return a + b;
    },
    subtract: function(a, b) {
        return a - b;
    }
};
export default mathOperations;
  • 在这个模块中,函数内部的 this 没有被意外地绑定到全局对象,使得模块更加独立和可维护。
  1. 事件处理:在事件处理函数中,严格模式可以使 this 的指向更加清晰。例如,在 DOM 事件处理中:
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF - 8">
    <title>Strict Mode in Event Handling</title>
</head>

<body>
    <button id="myButton">Click me</button>
    <script>
        'use strict';
        const button = document.getElementById('myButton');
        button.addEventListener('click', function() {
            console.log(this); // 指向button元素
        });
    </script>
</body>

</html>
  • 这里严格模式保证了事件处理函数中的 this 指向触发事件的 DOM 元素,使代码逻辑更易于理解和维护。

使用非严格模式在这些场景中可能带来的问题

  1. 模块开发:在非严格模式下,函数内部的 this 指向全局对象。这可能导致意外的全局变量赋值。例如:
// 非严格模式下的模块
function add(a, b) {
    this.result = a + b; // 意外地给全局对象添加了result属性
    return this.result;
}
  • 这样的代码可能会与其他模块或全局代码产生命名冲突,降低了模块的独立性和可维护性。
  1. 事件处理:在非严格模式下,事件处理函数中的 this 指向可能会因为一些复杂的调用场景而变得混乱。例如,当事件处理函数被赋值给一个变量并在其他地方调用时,this 可能不再指向预期的 DOM 元素。
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF - 8">
    <title>Non - strict Mode in Event Handling</title>
</head>

<body>
    <button id="myButton">Click me</button>
    <script>
        const button = document.getElementById('myButton');
        function handleClick() {
            console.log(this); // 在非严格模式下,这里的this指向可能会因调用方式改变而改变
        }
        button.addEventListener('click', handleClick);
        const newFunc = handleClick;
        newFunc(); // 这里的this可能不再指向button元素,而是全局对象
    </script>
</body>

</html>
  • 这种不确定性会导致代码难以调试和维护。