@Inject(REQUEST) 如何工作以及如何解构它

How @Inject(REQUEST) works and how to destructure it

第一个问题是注入的参数在 class 初始化后如何改变。因为这段代码有效

export class AppService {
  constructor(@Inject(REQUEST) private request) {}

  myMethod() {
    console.log(this.request.user.userId); // userId exists
  }
}

此代码无效

export class AppService {
  private user;

  constructor(@Inject(REQUEST) request) {
     console.log(request) // it has request but no user in it
     this.user = request?.user?.userId;
  }

  myMethod() {
     console.log(this.user); // undefined
  }
}

第二个示例没有 'userId',但应该由我的 nest.js 拦截器注入。如果这两个代码片段完全相同,为什么会这样呢?即使请求变量只指向对象,为什么它在第二种情况下不起作用?我只想解构请求对象以从中获取 userId。

As described by this question、JavaScript 通常是 pass-by-value 除了 对于通过引用传递的对象。因此,如果一个变量被分配给一个对象,它可以在以后看到对该对象的更改,但是如果它以某种方式被分配给一个原始对象(在这种情况下是一个对象的属性)那么它就不会看到当 属性 更新时,因为它仅按值传递。你可以在这里用一个简短的片段看到这个(运行 它在节点 REPL 或浏览器中)

const req = { foo: 'foo', fooBar: { foo: 'foo', bar: 'bar' } }
const bar = req.bar; // undefined passed by value
const fooBar = req.fooBar; // object passed by reference
const fooBarFoo = req.fooBar.foo; // undefined passed by value
req.bar = 'bar'
req.fooBar.fooBar = 'fooBar'
req.fooBar.foo = 'not foo'
console.log(req) // original object
console.log(bar) // still undefined
console.log(fooBar) // full object, with fooBar property and "not foo" for foo property
console.log(fooBarFoo) // still "foo"

这解释了为什么在构造函数中 req.user(和后续属性)是 undefined,但在方法中它工作正常。

为了能够使用 this.user,您可以做的是为您的 class 喜欢的

创建一个 getter
export class AppService {
  constructor(@Inject(REQUEST) private request) {}

  get user() {
    return this.request.user.userId
  }

  myMethod() {
    console.log(this.user); // userId exists
  }
}