javascript - 尝试继承 for 循环中按名称引用的所有类时出现问题

标签 javascript oop inheritance subclassing

好吧,标题很拗口,但我想不出更好的标题,欢迎提出想法。
无论如何,我有一个包含类作为属性的 javascript 对象。我想通过子类化它来创建另一个对象,该对象在各个方面都与第一个对象相同。我会尝试总结一下:

var L1 = {};

L1.Foo = function() {/*...*/};
L1.Bar = function() {/*...*/};
//...
L1.Baz = function() {/*...*/};

var L2 = {};

L2.Foo = function() { L1.Foo.call(this); /*possibily some other code here*/ };
L2.Foo.prototype = Object.create(L1.Foo.prototype);
L2.Foo.prototype.constructor = L2.Foo;

L2.Bar = function() { L1.Bar.call(this); /*possibily some other code here*/ };
L2.Bar.prototype = Object.create(L1.Bar.prototype);
L2.Bar.prototype.constructor = L2.Bar;

//...

L2.Baz = function() { L1.Baz.call(this); /*possibily some other code here*/ };
L2.Baz.prototype = Object.create(L1.Baz.prototype);
L2.Baz.prototype.constructor = L2.Baz;

var foo = new L2.Foo();
console.log(foo); //L2.Foo
var bar = new L2.Bar();
console.log(bar); //L2.Bar
var baz = new L2.Baz();
console.log(baz); //L2.Baz

First, working version .
我告诉自己:“嗯,看起来这里有一个模式”,所以我去修改了我的代码,如下所示:

//first 10 lines unaltered

for(prop in L1) {
    L2[prop] = function() { L1[prop].call(this); /*Call super method by default,
    unless overriden below*/ };
    L2[prop].prototype = Object.create(L1[prop].prototype);
    L2[prop].prototype.constructor = L2[prop];
}
//Here I decide that I want to override only the constructor
//for Foo, so naturally:
L2.Foo.prototype.constructor = function() {
    L1.Foo.call(this);
    this.someOtherProperty = "foo";
};

var foo = new L2.Foo();
console.log(foo); //L2.(anonymous function)?
console.log(foo.someOtherProperty); //undefined?
var bar = new L2.Bar();
console.log(bar); //L2.(anonymous function)?
var baz = new L2.Baz();
console.log(baz); //L2.(anonymous function)?

Second, not-so-working version .
我做错了什么?

最佳答案

"huh, looks like there a pattern here" so I went and modified my code as follows:

for(prop in L1) {
    L2[prop] = function() { L1[prop].call(this);

您已经找到了常见的closure in a loop problem - 所有 L2 函数实际上都在其新实例上调用 L1.Baz,因为 prop 的值为 “Baz”.请参阅链接的问题以了解如何解决此问题。

此外,请注意,您的构造函数中没有一个将其参数传递给 super 调用,这也可能会影响您。

<小时/>

Here I decide that I want to override only the constructor for Foo, so naturally:

L2.Foo.prototype.constructor = function() {
    L1.Foo.call(this);
    this.someOtherProperty = "foo";
};

What I am getting wrong?

覆盖原型(prototype)对象上的.constructor属性没有任何作用。您的代码仍在调用 new L2.Foo,而不是 new L2.Foo.prototype.constructor。您可能想看看how the new keyword works .

相反,您确实需要替换L2.Foo。这可以通过 this pattern 来完成:

L2.Foo = (function (original) {
    function Foo() {
        original.apply(this, arguments);   // apply old L2.Foo constructor
        this.someOtherProperty = "foo";    // set property
    }
    Foo.prototype = original.prototype; // reset prototype
    Foo.prototype.constructor = Foo; // fix constructor property
    return Foo;
})(L2.Foo);

(或者您只需输入第一个版本中的标准模式)。如果这确实过于重复,您还可以以编程方式执行 .prototype.constructor 设置:

// whole code
var L2 = {
    Foo: function() {
        L1.Foo.call(this);
        this.someOtherProperty = "foo";
    }
    // … other overwritten constructors
};
for (var prop in L1) {
    if (!L2[prop]) // unless overridden above, create default that only…
        (function(parent) {
            L2[prop] = function() {
                parent.apply(this, arguments); // calls super
            };
        }(L1[prop]));
    L2[prop].prototype = Object.create(L1[prop].prototype);
    L2[prop].prototype.constructor = L2[prop];
}

关于javascript - 尝试继承 for 循环中按名称引用的所有类时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26225222/

相关文章:

javascript - Marionette View 的正确 View 生命周期是什么?

javascript - jQuery ajax :error runs even if the response is OK 200

oop - 一些可重用代码的架构

c++ - 了解空继承类的未使用 typedef

javascript - node.js 本地模块 :cannot find module error

javascript - 运行 AWS Lambda 函数,无论 cron 事件如何(并检查 Mongo DB 连接是否已成功建立)?

C++ 模板(泛型编程)与多态性?

javascript - 在 Javascript ES6 的子类中扩展父类方法

c++:使用 header 但并非没有时对vtable的 undefined reference

C# 与 C++ : inheritance specifics