【问题标题】:JavaScript: Use parent methods from child class?JavaScript:使用子类的父方法?
【发布时间】:2013-10-13 08:41:36
【问题描述】:

我正在尝试在子类中使用父类中的方法。在其他语言中,您只需要使用extends,并且所有来自父级的方法都可以在子级中使用,但在 JavaScript 中,它似乎有所不同。

function Svg() {
    this.align = function(value) {
        if(value === 'left') return 0;
    }
}

function Graph() {
    // I want to align text to the left
    console.log('<text x="' + align('left') + '"></text>');
}

graph = new Graph();
Graph.prototype = new Svg();
Graph.prototype.align.call();

http://jsfiddle.net/cBMQg/9/

【问题讨论】:

  • 为什么align是一个全局变量?你想让它成为财产吗?
  • 我把它改成了this.align,我认为这是正确的?
  • 不要分配给Graph.prototype inside Graph 构造函数!!!
  • 抱歉,这真的很古怪,我一直在尝试一切,并且一直在冒险超出教程规范。我如何将这两个类联系在一起?
  • @MackieeE 我敢肯定这段代码对很多人来说是值得畏惧的 :)

标签: javascript polymorphism superclass subclassing


【解决方案1】:

我明白下面的代码不一定像其他 OOP 语言那样“扩展”。但它确实需要另一个函数/类作为属性——你可以直接调用它的方法。此外,我没有在这个演示中使用 JavaScript 原型设计。

<script>
    function Svg() {
        this.align = function( align ) {
            if( align == 'left') 
                return 'left';
            else
                return 0;
        }
    }

    function Graph() {

        this.Svg = new Svg();
        // I want to align text to the left
        this.AlignLeft = function( direction ) {
            console.log('<text x="' + this.Svg.align( direction ) + '"></text>');
        }
    }

    graph = new Graph();
    graph.AlignLeft('left');  //console.log <text x="left"></text> 
</script>

小提琴http://jsfiddle.net/cBMQg/11/

【讨论】:

  • 不知道为什么改成AlignLeft,抱歉!我以为是text-align 属性=)!
  • 你为什么不在这里使用原型?他们本来是合适的。顺便说一句,属性名称通常是小写的。
  • 嗨,Bergie,老实说,部分原因是我自己还没有完全掌握原型设计。对于像这个问题这样的例子:stackoverflow.com/questions/4691044/… 因为它们似乎对这两个例子都非常有效 - 鉴于您在 JavaScript 方面的经验,如果您可以包含在原型示例中,我会喜欢它(并且非常感谢它!),谢谢您也发表评论 - MackieeE =]
  • @MackieeE 示例包括,查看有关原型的更多信息的链接。您可以在控制台中复制并粘贴代码(在浏览器中按 F12)并运行它以查看它的作用并尽可能多地摆弄它以确保您理解它。
【解决方案2】:
function Svg() {
    this.align = function(value) {
        if(value === 'left') return 0;
    }
}

function Graph() {
     Svg.call(this); // Call the Super Class Constructor with changed THIS
    // I want to align text to the left
    console.log('<text x="' + align('left') + '"></text>');
}



graph = new Graph();
Graph.prototype = new Svg();
graph.align('left');

【讨论】:

【解决方案3】:

答案可能有效,但为什么不使用原型? align 函数会在每个实例上执行不同的逻辑吗?

正如贝尔吉指出的那样; JavaScript 使用原型来继承,最好在原型上定义成员在实例之间不会改变:

简单解释;原型可用于声明不会为实例更改的成员/属性。如果我声明一个名为 Person 的对象,并且 person 有 2 个成员:name 和 greet。 Greet 将输出“你好,我是 [this.name]”,因此 Greet 在实例之间不会改变。

当我在 Person 原型上声明 greet 方法,然后创建数千个 Person 实例(ben、jack、mary ....)时,它们将只共享一个 greet 函数。这为对象初始化节省了内存和 CPU 时间。查看此链接了解更多信息:https://stackoverflow.com/a/16063711/1641941

以下链接可能会帮助您了解 this 在 JavaScript 中所指的内容。 https://stackoverflow.com/a/19068438/1641941

function Svg() {
  this.someInstanceValue=22;
}
Svg.prototype.align = function(value) {
  if(value === 'left') return 0;
}
function Graph() {
    // get Svg's instance properties
    Svg.apply(this,arguments);
    console.log('<text x="' + this.align('left') + '"></text>');
}
//inherit from Svg:
Graph.prototype=Object.create(Svg.prototype);
Graph.prototype.constructor=Graph;

graph = new Graph();

graph.align('left');

如果您不想从 Svg 继承而是混合它,那么您仍然可以使用原型来混合它的功能(并调用 Svg.apply 以获取所需的实例成员):

function mixin(source, target){
  for(thing in source){
    if(source.hasOwnProperty(thing)){
      target[thing]=source[thing];
    }
  }
};
function Svg() {
  this.someInstanceValue=22;
}
Svg.prototype.align = function(value) {
  if(value === 'left') return 0;
}
function Graph() {
    // get Svg's instance properties
    Svg.apply(this,arguments);
    console.log('<text x="' + this.align('left') + '"></text>');
}
//mix in Svg:
mixin(Svg.prototype, Graph.prototype)

graph = new Graph();

graph.align('left');

【讨论】:

  • 感谢 HMR!实际上,我确实最终采用了类似这样的方法。
  • 唯一的区别是我使用调用而不是应用,我根据您对其他答案的评论更改了它。我也没有这个:Graph.prototype.constructor=Graph; 我读过重置构造函数。
  • @JohnSmith aplly 代替 call 当您有构造函数参数并且只想将它们全部传递给“父级”时会派上用场。如果您只需要传递某些参数,那么您应该使用 call 设置构造函数不是您的代码工作所必需的,但其他人可能会使用您的代码,当他们使用 newMe=new this.constructor(); 时,他们会得到错误的对象。
猜你喜欢
  • 1970-01-01
  • 2017-05-14
  • 2016-02-14
  • 1970-01-01
  • 2020-12-27
  • 2011-09-04
  • 1970-01-01
  • 2017-11-09
  • 2012-08-04
相关资源
最近更新 更多