JavaScript严格模式下函数内部this指向变化规律
- 全局作用域:在严格模式下,全局作用域中的
this
不再指向全局对象(如浏览器中的 window
),而是 undefined
。例如:
'use strict';
console.log(this); // undefined
- 函数调用:
- 普通函数调用:在严格模式下,函数内部的
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
- 构造函数调用:在严格模式下,构造函数内部的
this
指向新创建的对象实例。例如:
'use strict';
function Person(name) {
this.name = name;
}
const person = new Person('John');
console.log(person.name); // John
- 箭头函数:箭头函数没有自己的
this
绑定,它会捕获其所在上下文的 this
值。在严格模式下同样如此,箭头函数的 this
始终指向它定义时所在的作用域中的 this
。例如:
'use strict';
const obj = {
value: 42,
getThis: () => {
console.log(this);
}
};
obj.getThis(); // undefined(因为箭头函数的this指向全局作用域,严格模式下全局作用域this为undefined)
实际应用场景及利用特性编写健壮可维护代码
- 模块开发:
- 在模块开发中,严格模式有助于避免意外的全局变量声明。例如,当在模块中定义函数时,严格模式下函数内部的
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
没有被意外地绑定到全局对象,使得模块更加独立和可维护。
- 事件处理:在事件处理函数中,严格模式可以使
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 元素,使代码逻辑更易于理解和维护。
使用非严格模式在这些场景中可能带来的问题
- 模块开发:在非严格模式下,函数内部的
this
指向全局对象。这可能导致意外的全局变量赋值。例如:
// 非严格模式下的模块
function add(a, b) {
this.result = a + b; // 意外地给全局对象添加了result属性
return this.result;
}
- 这样的代码可能会与其他模块或全局代码产生命名冲突,降低了模块的独立性和可维护性。
- 事件处理:在非严格模式下,事件处理函数中的
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>