ES6构造函数返回基类的实例?

时间:2016-05-19 17:15:35

标签: javascript inheritance constructor ecmascript-6 derived-class

派生类的构造函数返回基类的实例。

以下代码解释了我的问题:

// Vector is defined by an external module (Unreal.js)
class TestB extends Vector {
    constructor() {
        super();
    }
    Log() {
        console.log("" + this);
    }
}
console.log(new TestB() instanceof TestB) // returns false !!! why ??? 
console.log(new TestB() instanceof Vector) // returns true...

class TestA extends Array {
    constructor() {
        super();
    }
    Log() {
        console.log("" + this);
    }
}
console.log(new TestA() instanceof TestA); // returns true, all is good

这怎么可能?

2 个答案:

答案 0 :(得分:10)

Vector似乎是以与class不兼容的方式实施的。

以下是Vector单向执行此操作的示例:

function Vector() {
  var v = Object.create(Vector.prototype);
  return v;
}

class TestB extends Vector {
  constructor() {
    super();
  }
}

console.log(new TestB() instanceof TestB);  // false
console.log(new TestB() instanceof Vector); // true

这里的关键是,由于Vector返回的对象与创建的new对象不同,因此它的类型错误。关于构造函数的一个相对鲜为人知的事情是,如果它们返回非null对象引用,则new Constructor的结果是构造函数返回的对象,而不是创建的对象new

以下是浏览器支持class的人的代码段:



function Vector() {
  var v = Object.create(Vector.prototype);
  return v;
}

class TestB extends Vector {
  constructor() {
    super();
  }
}

console.log(new TestB() instanceof TestB); // false
console.log(new TestB() instanceof Vector); // true




...以及live copy on Babel's REPL对于那些浏览器没有的人来说。

令我惊讶的是,Babel和Chrome都允许我使用class Vector执行此操作并返回constructor的值;我还没有从规范中弄清楚它是否真的有效:



class Vector {
  constructor() {
    var v = Object.create(Vector.prototype);
    return v;
  }
}

class TestB extends Vector {
  constructor() {
    super();
  }
}

console.log(new TestB() instanceof TestB); // false
console.log(new TestB() instanceof Vector); // true




要解决这个问题,您可能需要使用每个实例的黑客攻击,例如将所有TestB.prototype方法复制到实例上。理想情况下,尝试通过聚合(又称"组合",例如,通过将Vector实例作为您班级实例的属性)来尝试使用Vector,而不是黑客攻击而不是继承,因为它没有设置继承。

答案 1 :(得分:1)

我不知道此问题的确切原因,但黑客 proto 解决了这个问题。 :)

ContinueWith(async task => 
{    
    using (var streamWriter = new StreamWriter(File, true))
    {
       using (var textWriter = TextWriter.Synchronized(streamWriter))
       {
           textWriter.WriteLine(base.RenderLoggingEvent(loggingEvent));
           await textWriter.FlushAsync();
        }
     }
}, TaskContinuationOptions.OnlyOnFaulted);