Use of Class.apply in the context of a specialized class

Asked

Viewed 30 times

3

I saw an example that dealt with Class father and Class daughter where, at the beginning of the specialized class, it was like this:

var ClasseFilha = function ClasseFilha (){
    ClassePai.apply(this, arguments);

    ...
};

Although I understand how the apply and see how the daughter class changes in passing through the second line (use this before and after the apply bring different results), I get confused as the ClassePai.apply() modify the ClasseFilha without a direct assignment on a variable, for example.

I would like a more theoretical explanation for this, if possible.

  • 2

    On the question, if you have familiarity with OOP, it amounts to a call super().

  • 1

    Yes, that I understand. I don’t understand how the call works within the JS engine logic. How does apply modify this? How does this in the context of the daughter class inherit the parent class methods after the passage of line two? This is one of the characteristics of apply?

  • bfavaretto explained even better than me. If you have doubts ask/comments. If it was solved I find his answer more complete.

2 answers

3


Briefly, this apply will execute the parent class constructor in the context of the daughter class. That’s what it does, calls a function forcing a value to this within it. That is, any reference to this in the builder ClassePai will be referring to the this which has just been created in the execution of new ClasseFilha(...).

You said:

I get confused like the ClassePai.apply() modify the ClasseFilha without a direct assignment on a variable

Actually you’re not modifying ClasseFilha (which is a constructor), rather an object that is being instantiated with new ClasseFilha(). And not necessarily you are modifying, it depends on what the builder ClassePai makes. If you are familiar with OOP, the line of apply is equivalent to a call from super() in languages that implement class-based OOP (JS is based in prototypes).

You commented:

How apply modifies this?

The this in itself (the reference) is not modified. The object to which it points - which has just been created with new ClasseFilha() - can be changed by the function ClassePai. This will depend on the code of this function. And it will depend on the context where the code snippet you posted is inserted. Which leads to your next question:

How does this in the context of the daughter class inherit the parent class methods after the passage of line two? This is one of the characteristics of apply?

This kind of construction usually comes in a context like this:

var ClassePai = function ClassePai(nome) {
    this.nome = nome;
};

var ClasseFilha = function ClasseFilha (){
    ClassePai.apply(this, arguments);
};

var filho = new ClasseFilha('nome do filho');

In this case, the object filho will win an estate nome which is "injected" into it by the father builder. The call of the apply only guarantees the execution of the superclass constructor. Its methods are not available. If the constructor ClassePai Trying to execute a method that is part of your prototype will be a mistake, because in that code the daughter class does not inherit the prototype from the father. But it is possible to inherit, so:

var ClassePai = function ClassePai(nome) {
    this.nome = nome;
    this.ola();
};

ClassePai.prototype = {
    ola: function() {
        console.log('Olá, meu nome é ' + this.nome);
    }
};

var ClasseFilha = function ClasseFilha (){
    ClassePai.apply(this, arguments);
};

// Sem a linha abaixo, o construtor do pai
// daria erro na chamada a this.ola.
// Esta linha é que arma a herança entre as classes
// (coloca as duas na mesma cadeia de protótipos)
ClasseFilha.prototype = Object.create(ClassePai.prototype);

var filho = new ClasseFilha('nome do filho');

  • I don’t know if I’m being clear, if you’re not asking here in the comments.

  • Excellent, I understood perfectly. Thank you very much!

3

When you "lend" the this via ClassePai.apply(this, arguments); you allow the ClassePai to modify the this which belongs to the ClasseFilha. This allows to extend the class if the code so wants.

An example:

function ClassePai(nome, idade) {
  this.nome = nome;
  this.idade = idade;
  this.dizerNome = function() {
    console.log(this.nome);
  }
}

var ClasseFilha = function ClasseFilha() {
  ClassePai.apply(this, arguments);
  this.naturalidade = arguments[2];
  this.naturalDe = function(){
    console.log(this.naturalidade);
  }
};

var pessoaA = new ClasseFilha('Pedro', 34, 'Portugal');
var pessoaB = new ClasseFilha('Ana', 34, 'Brazil');

pessoaA.dizerNome();
pessoaB.dizerNome();
pessoaB.naturalDe();

Moreover the @bfavaretto explanation is quite complete

  • @Brunno notes that in Sergio’s example the daughter class does not inherit anything from the parent class. The method dizerNome is not in the parent prototype, each instance created will gain its own copy of that method. (Sergio, I tried to find question about it here on the site but I did not find; it is not possible, must have some).

  • 2

    @bfavaretto also not find. The nearest is the concept of mixin which in this case even applies.

  • Sergio, I just chose the reply of the bfavaretto for being more scrupulous, but I also appreciate your willingness to help.

  • @Brunnovianna you did very well! He’s usually better at explaining than me :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.