this 绑定
现在的水平应该写出来的内容不一样了 应该更有意义了 有实现案例了
node中的this和浏览器环境的this有什么不同
在 Node.js 和 浏览器 环境中,this 的行为确实有所不同,主要受 运行环境 和 调用方式 影响。以下是它们的主要区别:
1. 全局作用域中的 this
| 环境 | this 的值 |
|---|---|
| Node.js | global(在 ES 模块中是 undefined) |
| 浏览器 | window(或 globalThis) |
🌟 代码示例:
js
console.log(this);- 在浏览器中:输出
window - 在 Node.js 中(CommonJS):输出
global - 在 Node.js 中(ES 模块):输出
undefined
2. 模块作用域中的 this
在 Node.js 中,每个文件都被视为一个 模块,而 this 在模块级作用域内不会指向 global,而是指向 module.exports。
🌟 代码示例:
js
// Node.js 中
console.log(this === module.exports); // true
console.log(this === exports); // true在浏览器中,JavaScript 文件中的 this 仍然是 window(除非是 ES 模块)。
js
console.log(this === window); // true (非 strict 模式)3. 函数作用域中的 this
✅ 普通函数
- 在 Node.js 和 浏览器 的 非严格模式 下,
this指向 全局对象(global/window)。 - 在 严格模式(
use strict) 下,this是undefined。
js
function test() {
console.log(this);
}
test();- 浏览器(非严格模式)→
window - 浏览器(严格模式)→
undefined - Node.js(非严格模式)→
global - Node.js(严格模式)→
undefined
✅ 对象方法
在 Node.js 和浏览器 中,对象的方法 this 指向调用它的对象:
js
const obj = {
name: "test",
getName() {
console.log(this.name);
},
};
obj.getName(); // "test"✅ 箭头函数
箭头函数的 this 是 在定义时绑定的,不会因为调用方式不同而改变:
js
const obj = {
name: "test",
getName: () => {
console.log(this.name);
},
};
obj.getName(); // 在浏览器和 Node.js 中都是 `undefined`(`this` 继承自外层作用域)4. 类和构造函数中的 this
在 Node.js 和浏览器 中,类和构造函数的 this 指向 新创建的实例。
js
class Person {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
const p = new Person("Alice");
p.sayName(); // Alice但是在 Node.js REPL(交互式环境) 运行时,可能会有特殊情况,比如 this 可能是 global,而不是 undefined。
5. setTimeout / setInterval 中的 this
- 浏览器:
setTimeout和setInterval内部的this默认指向window(非严格模式)。 - Node.js:
setTimeout和setInterval内部的this指向Timeout对象,而不是global。
🌟 代码示例:
js
setTimeout(function () {
console.log(this);
}, 1000);- 浏览器:
window - Node.js:
Timeout(即{ _idleTimeout, _onTimeout, ... })
6. EventEmitter 中的 this(Node.js 专有)
在 Node.js 的 EventEmitter 事件监听器中,this 默认指向 触发事件的对象。
js
const EventEmitter = require("events");
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on("event", function () {
console.log(this === myEmitter); // true
});
myEmitter.emit("event");在浏览器的 addEventListener 中,普通函数的 this 指向 触发事件的 DOM 元素,而箭头函数的 this 指向 外层作用域。
js
document.body.addEventListener("click", function () {
console.log(this); // <body>
});
document.body.addEventListener("click", () => {
console.log(this); // Window(箭头函数继承外层作用域)
});7. 结论
| 场景 | Node.js(CommonJS) | Node.js(ES 模块) | 浏览器 |
|---|---|---|---|
| 全局作用域 | global | undefined | window |
| 模块作用域 | module.exports | undefined | window |
| 普通函数(非严格模式) | global | global | window |
| 普通函数(严格模式) | undefined | undefined | undefined |
| 对象方法 | 调用对象 | 调用对象 | 调用对象 |
| 箭头函数 | 继承外层作用域 | 继承外层作用域 | 继承外层作用域 |
| 类构造函数 | 实例对象 | 实例对象 | 实例对象 |
| setTimeout | Timeout | Timeout | window |
| 事件监听器 | EventEmitter | EventEmitter | 触发事件的元素 |