instanceof Parent 和 instanceof super.constructor 有什么区别?

What is the difference between instanceof Parent and instanceof super.constructor?

我有一个 class Parent,还有一个 class Child 扩展 Parent。 在 Parent 的构造函数中,我现在需要确定 x 是原始 class 还是子 class.

的实例

在我的情况下 Parent 实际上是匿名的 我使用的 instanceof of this.constructor 没有按预期工作:

class Parent {
  constructor(x) {
    if (x instanceof this.constructor) {
      console.log("x is instanceof of this.constructor");
    }
    if (x instanceof Parent) {
      console.log("x is instanceof of Parent");
    }
  }
}

class Child extends Parent {
  constructor(x) {
    super(x);
  }
  foo(x) {
    new this.constructor(new super.constructor(x))
  }
}

通话中

new Child().foo()

现在产生 x is instanceof of Parent 而不是 x is instanceof of this.constructor。我做错了什么?如何在不使用 x is instanceof of *Parent* 的情况下解决此问题?


所有这一切的原因是我包装了我的 class 定义,这样我就可以创建一个没有 new 的新实例。 class赋值给wrapping/mutating后的Parent,所以被包裹的class应该是匿名的

我不知道这是否有意义,我的简化示例可能无法阐明所有这些的意义所在,但除了上面解释的一个问题外,它实际上非常方便:

X()   // create new instance of Parent without new
X.f   // access static methods
const { X, c: Parent } = function (c) {
    return {
        X: Object.assign(
            function () {
                return new c(...arguments);
            },
            _.pick(c, Object.getOwnPropertyNames(c)  // using lodash here
                .filter(n => typeof c[n] === "function")
            )
        ),
        c
    };
}(class {
  constructor(x) {
    if (x instanceof this.constructor) {
      console.log("x is instanceof of this.constructor");
    }
    if (x instanceof Parent) {
      console.log("x is instanceof of Parent");
    }
  }
})

class Child extends Parent {
  constructor(x) {
    super(x);
  }
  foo(x) {
    new this.constructor(new super.constructor(x))
  }
}

首先ParentChild标识符的绑定是Parent和Childclass构造函数和常量。当用作 Object.assign 的第一个参数时,尚未创建 Parent 绑定 但是 当方法被分配给函数 c 时,函数实际上并没有被调用。因此,当稍后调用 class 构造函数代码时, ParentChild 变量都引用适当的 class 构造函数。

因此

class {
  constructor(x) {
    if (x instanceof Parent) {
      console.log("x is instanceof of Parent");
      if( x instance of Child) {
      console.log("x is instance of Child");
    }
  }
}

应该指出参数是 Parent 还是 Child 的实例。当然,因为 class 扩展将 Parent.prototype 放在 Child.prototype 继承链的头部,所以 Child 的每个实例也是 Parent 的实例。

代码检查 instanceof 值的结果符合预期:

  1. foo 创建一个 [Object Parent] 对象参数传递给 Child 构造函数

  2. Child 使用提供的参数调用超级构造函数,其形式为:

      super([Parent Object])
    

    super 看到的 this 值设置为新的 Child 对象实例。

  3. 在超级构造函数中,[Object Parent] x 参数不是 this.constructor 的实例,它是 Child,因此不会生成这样的消息。

您可能希望查看是否可以通过使用较少的复杂性来简化完整代码,按照以下结构:

 class Parent {..........}
 class Child extends Parent {.....}
 const X = Object.assign(.......)