Skip to content

this 绑定

现在的水平应该写出来的内容不一样了 应该更有意义了 有实现案例了

node中的this和浏览器环境的this有什么不同

Node.js浏览器 环境中,this 的行为确实有所不同,主要受 运行环境调用方式 影响。以下是它们的主要区别:


1. 全局作用域中的 this

环境this 的值
Node.jsglobal(在 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 下,thisundefined
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

  • 浏览器setTimeoutsetInterval 内部的 this 默认指向 window(非严格模式)。
  • Node.jssetTimeoutsetInterval 内部的 this 指向 Timeout 对象,而不是 global

🌟 代码示例:

js
setTimeout(function () {
  console.log(this);
}, 1000);
  • 浏览器window
  • Node.jsTimeout(即 { _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 模块)浏览器
全局作用域globalundefinedwindow
模块作用域module.exportsundefinedwindow
普通函数(非严格模式)globalglobalwindow
普通函数(严格模式)undefinedundefinedundefined
对象方法调用对象调用对象调用对象
箭头函数继承外层作用域继承外层作用域继承外层作用域
类构造函数实例对象实例对象实例对象
setTimeoutTimeoutTimeoutwindow
事件监听器EventEmitterEventEmitter触发事件的元素