JavaScript: использовать родительские методы из дочернего класса?

Я пытаюсь использовать метод из родительского класса внутри дочернего класса. В других языках вам просто нужно было бы использовать 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/


person John Smith    schedule 06.10.2013    source источник
comment
Почему align является глобальной переменной? Вы хотели, чтобы это стало собственностью?   -  person Bergi    schedule 07.10.2013
comment
Я изменил его на this.align, что, по-моему, правильно?   -  person John Smith    schedule 07.10.2013
comment
Не назначайте Graph.prototype внутри конструктора Graph!!!   -  person Bergi    schedule 07.10.2013
comment
Извините, это стало действительно дурацким, я пробовал все и рискнул выйти за рамки учебных норм. Как мне связать два класса вместе?   -  person John Smith    schedule 07.10.2013
comment
@JohnSmith Вот что обычно влечет за собой игра и обучение: D   -  person MackieeE    schedule 07.10.2013
comment
@MackieeE Я уверен, что этот код достоин многих людей :)   -  person John Smith    schedule 07.10.2013


Ответы (3)


Я понимаю, что приведенный ниже код не обязательно «расширяется», как в других языках ООП. Но он принимает другую функцию/класс в качестве свойства, для которого вы можете напрямую вызывать его методы. Кроме того, я не использовал прототипирование 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/

person MackieeE    schedule 06.10.2013
comment
Я не знаю, почему изменил его на AlignLeft, извините! Я думал, что это для свойства text-align =)! - person MackieeE; 07.10.2013
comment
Почему вы не использовали здесь прототипы? Они были бы уместны. Кстати, имена свойств обычно пишутся в нижнем регистре. - person Bergi; 07.10.2013
comment
Привет, Берги, я буду очень честен и скажу отчасти потому, что сам еще не полностью освоил прототипирование. Для примера, подобного этому вопросу: stackoverflow.com /questions/4691044/, где, поскольку они кажутся очень подходящими для обоих примеров - учитывая ваш опыт работы с JavaScript, я был бы рад (и очень признателен!), если бы вы могли включить его в пример прототипа, спасибо за ваш комментарий также - MackieeE =] - person MackieeE; 07.10.2013
comment
Пример @MackieeE включает, проверьте ссылку на дополнительную информацию для прототипа. Вы можете скопировать и вставить код в консоль (нажмите F12 в своем браузере) и запустить его, чтобы увидеть, что он делает, и возиться с ним столько, сколько хотите, чтобы убедиться, что вы его понимаете. - person HMR; 07.10.2013

Ответы, вероятно, работают, но почему не используется прототип? Будет ли функция align выполнять разную логику для каждого экземпляра?

Как указал Берги; JavaScript использует прототип для наследования, и лучше определить члены прототипа, которые не меняются между экземплярами:

Просто объяснил; прототип может использоваться для объявления членов/свойств, которые не будут меняться для экземпляра. Если я объявляю объект с именем Person, а у человека есть 2 члена: имя и приветствие. Приветствие выводит «Привет, я [это.имя]», поэтому приветствие не меняется между экземплярами.

Когда я объявлю метод приветствия в прототипе Person, а затем создам тысячи экземпляров Person (бен, джек, мэри ....), все они будут использовать только одну функцию greet. Это экономит память и процессорное время для инициализации объекта. Перейдите по этой ссылке для получения дополнительной информации: 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');
person HMR    schedule 07.10.2013
comment
спасибо ХМР! Я действительно в конечном итоге следовал подходу, очень похожему на этот. - person John Smith; 08.10.2013
comment
единственная разница в том, что я использовал вызов вместо применения, я изменил это на основе вашего комментария к другому ответу. У меня также не было этого: Graph.prototype.constructor=Graph; который я прочитал, сбрасывает конструктор. - person John Smith; 08.10.2013
comment
@JohnSmith aplly вместо call может пригодиться, когда у вас есть параметры конструктора и вы просто хотите передать их все родителю. Если вам нужно передать только определенные параметры, вам следует использовать call Установка конструктора не требуется для работы вашего кода, но другие могут использовать ваш код, и когда они используют newMe=new this.constructor();, они получат неправильный объект. - person HMR; 08.10.2013