【问题标题】:ES6 Factory Pattern this is undefinedES6 工厂模式这是未定义的
【发布时间】:2015-08-17 19:01:13
【问题描述】:

我开始接触 ES6 并在 Javascript 中为实时项目实现设计模式。我有以下代码示例 sn-p,它会引发错误,指出 this 关键字的计算结果为未定义:

export let LifecycleFactoryObj = (() => {
  this.myCollection = new WeakSet();
  //.... More here
  this.add = function (opts) {
    let tempObject = new MyCollection(opts);
    this.myCollection.add(tempObject);
    if (this.myCollection.has(tempObject)) {
      return tempObject;
     }
    return null;
  };
})();

抛出的错误是:

undefined.lifecycles = new WeakSet(); ^ TypeError:无法设置未定义的属性“生命周期”

看起来 IIFE 中的 this 被评估为 undefined 但我似乎无法追踪原因。我认为 ES6 在使用 let 进行变量实例化时正确地限定了 this 关键字的范围。

谢谢!

【问题讨论】:

  • 那么您期望this 是什么?是的,它不限于函数。
  • 在 Javascript 中,一切都是对象。命名和匿名的函数。对于具有 OO 背景的人来说,完全理解 this 关键字、它的作用域、闭包等可能有点令人困惑。如果这是一个分配给变量的匿名函数,我认为 this 将引用函数对象,它变量有一个引用。
  • 好吧,对于一个人来说,您没有将匿名函数分配给变量,而是调用它的结果(这是undefined btw)。不,the value of this 是由函数调用决定的,而不是由一些不相关的变量决定的。它几乎从不指向被调用的函数。
  • 有意义的只是学习曲线。但这是有道理的,MDN 文章及其参考非常有帮助,谢谢。

标签: javascript design-patterns scope ecmascript-6


【解决方案1】:

this 没有在 ES6 中定义,如果你不使用构造函数或者还没有对象的话;您需要使用传统语法 (function ClassName) 或新语法 (class ClassName) 来创建构造函数,然后调用该构造函数。

在您的情况下,似乎不需要完整的类,因此请尝试使用普通对象:

export let LifecycleFactoryObj = {
    myCollection: new WeakSet(),
    //.... More here
    add: function(opts) {
        let tempObject = new MyCollection(opts);
        this.myCollection.add(tempObject);
        if (this.myCollection.has(tempObject)) {
            return tempObject;
        }
        return null;
    }
};

【讨论】:

  • “如果你不使用构造函数或者还没有对象,这在 ES6 中没有定义;” 好吧,我可以foo.call(bar)this 内的foo 设置为bar(假设它是一个常规函数)。
  • 确实如此。默认情况下,如果没有我提到的方法,函数没有this 关联。
  • @mc10 let x = {a:1, b:function() { return this.a; }}; x.b(); //=> 1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 2015-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多