【问题标题】:How "this" reference is transferred in the following function如何在以下函数中传输“this”引用
【发布时间】:2019-12-03 04:10:31
【问题描述】:

在 JS 手册中,我有以下示例,它工作正常:

let worker = {
  someMethod() {
    return 1;
  },

  slow(x) {
    alert("Called with " + x);
    return x * this.someMethod(); // (*)
  }
};

function cachingDecorator(func) {
  let cache = new Map();
  return function(x) {
    if (cache.has(x)) {
      return cache.get(x);
    }
    let result = func.call(this, x); // теперь 'this' передаётся правильно
    cache.set(x, result);
    return result;
  };
}

worker.slow = cachingDecorator(worker.slow); // теперь сделаем её кеширующей

alert( worker.slow(2) ); // работает
alert( worker.slow(2) ); // работает, не вызывая первоначальную функцию (кешируется)

问题是:如果没有在对象内部声明cachingDecorator,并且像worker.slow = cachingDecorator(worker.slow)一样调用,“this”引用如何传递到cachingDecorator函数中?我讲的是cacheDecorator里面的这一行:let result = func.call(this, x)

【问题讨论】:

    标签: javascript decorator


    【解决方案1】:

    this 引用在实际使用装饰器时在最后 2 行传输,因为 worker 对象在点之前。

    【讨论】:

      【解决方案2】:

      this 实际上不在cachingDecorator 中,而是在返回的匿名函数中。所以 this 值直到 that 函数被调用后才被设置。

      由于该函数已分配给worker.slow,并且您是从该对象调用它,所以this 值被设置为worker 对象。

      要记住的重要一点是this 有点像一个奇怪的函数参数。它只有一个名称的关键字,并且总是被设置(箭头函数除外)。它是根据如何调用函数来设置的,而不是像通过传递参数的常规参数那样设置。

      【讨论】:

        【解决方案3】:

        请注意,函数cachingDecorator 返回一个声明为function(x) {. . .} 的函数。任何像这样的函数在作为对象成员的引用被调用时都会继承上下文:

        function magicFn() { return this }
        const x = { magicFn };
        const y = { someKey: 6, magicFn };
        x.magicFn(); // === x, because it was invoked as x.magicFn
        y.magicFn(); // === y
        magicFn(); // === undefined, no `this` object member reference
        

        因此,当调用 worker.slow = cachingDecorator(worker.slow) 时,生成的函数会使用 worker.slow.call(this, x); 调用原始的 worker.slow,它代理传入的 this 值(在本例中为 worker)。

        【讨论】:

          猜你喜欢
          • 2011-07-02
          • 2011-04-07
          • 1970-01-01
          • 2011-10-21
          • 2023-03-07
          • 2012-09-16
          • 1970-01-01
          • 1970-01-01
          • 2011-12-28
          相关资源
          最近更新 更多