我正在创建一个矩阵类(用于反应应用),我想用这种方式定义:
class Matrix extends Object {
constructor(r, c) {
super();
this.rows = new Array(r);
for (var i=0; i<r; i++) {
this.rows[i] = new Array(c);
}
this.assign((v,i,j) => (i===j)? 1:0); // ERROR HERE
}
assign(f) {
for (var i=0; i<this.rows.length; i++) {
for (var j=0; j<this.rows[i].length; j++) {
this.rows[i][j] = f(this.rows[i][j], i, j);
}
}
}
// and so on
这可以通过webpack编译好,但是在运行时,我在chrome控制台中收到一条错误,说 _this.assign不是函数。
我可以这样做:
constructor(r, c) {
super();
this.rows = new Array(r);
for (var i=0; i<r; i++) {
this.rows[i] = new Array(c);
}
this.assign = function(f) {
for (var i=0; i<r; i++) {
for (var j=0; j<r; j++) {
this.rows[i][j] = f(this.rows[i][j], i, j);
}
}
};
this.assign((v,i,j) => (i===j)? 1:0);
}
但这是错的,对吧?我不必在构造函数中定义所有对象的函数,对吧?在同一个文件中,我定义了反应类,如:
class MatrixComponent extends React.Component { ... }
那些能够调用函数而不在构造函数中定义它们。我错过了什么?
答案 0 :(得分:3)
删除extends Object
和super()
来电似乎对我有用。
class Matrix { // extends Object {
constructor(r, c) {
// super();
this.assign();
}
assign() {
}
}
每个类已经在其原型链中具有Object,因此您不会通过扩展Object获得任何东西。 extends Object
是隐含的,因此请将其删除。
似乎extends Object
的处理是Babel中的一个错误。 Chromium浏览器的内置es6引擎处理代码很好,因为它已在此处修复:https://bugs.chromium.org/p/v8/issues/detail?id=3886
但看起来Babel的编号已被打破。
为了解释这种行为,让我们看一下来自babel的转换后的es5。
鉴于这个es6:
class OtherClass {}
class OtherClassExtender extends OtherClass {
constructor(r, c) {
super();
this.assign();
}
assign() {
}
}
class ObjectExtender extends Object {
constructor(r, c) {
super();
this.assign();
}
assign() {
}
}
new OtherClassExtender(1, 2);
new ObjectExtender(1, 2);
我们只会拍摄一下已编译的es5片段。我删除了很多代码。这不是完整的来源:
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else {
return self;
}
}
var OtherClass = function OtherClass() {};
var OtherClassExtender = function (_OtherClass) {
function OtherClassExtender(r, c) {
var _this = _possibleConstructorReturn(this, _OtherClass.call(this));
_this.assign();
return _this;
}
OtherClassExtender.prototype.assign = function assign() {};
return OtherClassExtender;
}(OtherClass);
var ObjectExtender = function (_Object) {
function ObjectExtender(r, c) {
var _this2 = _possibleConstructorReturn(this, _Object.call(this));
_this2.assign();
return _this2;
}
ObjectExtender.prototype.assign = function assign() {};
return ObjectExtender;
}(Object);
new OtherClassExtender(1, 2);
new ObjectExtender(1, 2);
_possibleConstructorReturn
基本上是super
,其中Babel保留了班级的参考资料。超类所以方法调用可以正确遍历继承层次结构。它基本上说&#34;超类有定义的方法,所以让我们看看方法(如assign
)&#34;。将Object
本身添加到该层次结构中没有任何意义,因为Javascript中的任何对象无论如何都将从Object
继承方法。
通过逐步修改已转换的代码,_possibleConstructorReturn(OtherClassExtender, OtherClass)
表示typeof call
为undefined
,因此返回OtherClassExtender
。
_possibleConstructorReturn(ObjectExtender, Object)
说typeof call
为object
,因此返回Object
。
对象实例没有assign
方法。 assign
类是Object
类的类方法,例如(new Object).assign
上不存在。
答案 1 :(得分:0)
通过反复试验,我发现延长null
与Object
,解决了问题:
class Matrix extends null { ... }
我想这是一个答案,但我对于为什么以及我试图这样做有什么不对而感到困惑。 我会高兴地标记出比这更好的答案:这真的解释了这些东西是如何运作的。