How to overwrite a method via prototype on a javascript object?

Asked

Viewed 1,333 times

3

Hello!

I’m studying javascript, but specifically Parasitic Combination Inheritance, and came across the methods override. It turns out I created the following code:

var Base = function(nome, texto) {
    this.name = nome;
    this.text = texto;
    this.saudacao = function() {
          return this.text + ' ' + this.name;
    }
}

var heranca = function(p, f) {
    var pc = Object.create(p.prototype);
    f.prototype = pc;
    f.prototype.constructor = f;
}

var Dia = function(texto) {
    Base.call(this, 'Fulano? ', 'Tudo bem, ');
    this.newText = texto;
}
heranca(Base, Dia);
Dia.prototype.saudacao = function() {
    var msg = this.saudacao();
    return msg + ' ' + this.newText;
}

var ola = new Dia('Bom dia!');
alert(ola.saudacao());

When executing Alert(hello(greeting)), I have the return of the parent class, not the superscript.

For testing, I changed the name of the method "greeting" of the class "day" to "novaSaudacao" and, executing Alert(hello.novaSaudacao()), I get the correct output.

Apparently the code written in dia.prototype.saudacao = Function() {} is not even executed (I added an Alert('! ') in him and it had no effect).

Hence the question: how to work correctly with the superscript of methods in javascript without forgetting the Parasitic Combination Inheritance?

EDIT I will try to explain the practical application to clarify the issue a little. The objects used as an example are not in question, only their functionalities.

Consider a class that calls itself "Kindness" and has the method "Greeting".

In creating...

var ola = new Gentileza("José");

We can execute...

ola. Greeting();

And as a result, "Hello, Jose.".

Now, we need two other objects called "Day" and "Night" which are children of "Kindness". So we can create...

var dia = new Dia("José");

And execute...

day. Greeting();

Now, the message will be "Hello Joseph. Good morning!". The first part of the message ("Hello, Joseph.") was generated in the parent object (Kindness). The "Day" object inherited the greeting from the parent object and added "Good morning!" to the text.

For the purpose of completion: I intend that my child class inherits a parent class method and complements it.

Thank you for your attention.

  • 1

    What you want with the line var msg = this.saudacao(); ? I couldn’t tell from your code...

  • What final return you want?

  • Brnper The variable "msg" contains the recovered text of the parent class. I use it just below by adding a text to complement the greeting and include a "good morning". It could also be Return this.saudacao() + ' ' + this.newText.

  • Fabianolothor, the return should be: "All right, so-and-so? Good morning!"

  • His parent class creates a method that "overwrites" (Shadows) what is in the prototype. It seems that you are understanding the opposite, but it is not very clear the question.

3 answers

3


I think I understand what is confusing you. The operations you do, in short, are:

  1. Establishes class inheritance base for class dia (note: it is convention to use uppercase initials for class names or constructs functions, but you used lowercase letters)

  2. Creates a new method saudacao in the prototype of dia.

  3. Creates instance of dia and executes the method saudacao hers.

Your logic is that dia.prototype.saudacao should override the existing greeting method at the base. This would be true if the method were in the prototype of base. However, it is created in the instance (this):

this.saudacao = function() {
      return this.text + ' ' + this.name;
}

And the builder of dia the execution of the manufacturer of base:

base.call(this, 'Fulano? ', 'Tudo bem, ');

Thus, the method saudacao executed in ola.saudacao() is defined within the constructor base, not what is in dia.prototype.

Methods present in the instance always have priority over what is in the prototype chain. When you run ola.saudacao, the first thing that is checked is whether the object itself ola owns a property saudacao. And he does, because of that call base.call(this, ...). Then this one runs. Only if it didn’t exist would it be checked dia.prototype and then base.prototype.

You would get the result you want with the following code:

var Base = function(nome, texto) {
    this.name = nome;
    this.text = texto;
}

Base.prototype.saudacao = function() {
		return this.text + ' ' + this.name;
}

var heranca = function(p, f) {
    var pc = Object.create(p.prototype);
    f.prototype = pc;
    f.prototype.constructor = f;
}

var Dia = function(texto) {
    Base.call(this, 'Fulano? ', 'Tudo bem, ');
    this.newText = texto;
}

heranca(Base, Dia);

Dia.prototype.saudacao = function() {
    var msg = Base.prototype.saudacao.call(this);
    return msg + ' ' + this.newText;
}

var ola = new Dia('Bom dia!');
alert(ola.saudacao());

It just doesn’t seem like a good way. It is that it seems that you want to do two things at once: overwrite a method, but at the same time have access to the overload method from within the method that overwrites it. It seems more case for functional style function composition than case for inheritance use.

  • I think not, that what you said would make sense if instead dia.prototype.saudacao = he did base.prototype.saudacao = and it worked, in case the prototype is not being overwritten, for some reason.

  • @Fabianolothor stay with you. My intention was, after inherit class methods and properties base (I apologize for the tiny), overwrite the method using dia.prototype.saudacao = ..., as mentioned. But, not so, then, how to overwrite the method stated in the father, now in the son?

  • I’m giving a check @Leikovsk, I’m curious now too.

  • @Leikovsk I added more information in the reply, see if it is now clearer

  • @bfavaretto I made a change to the code and removed the method from the instance. I also understood what @Fabianolothor meant about calling this.saudacao inside Dia.prototype.saudacao. The problem has been solved using all the tips here. I will put the code rewritten and comment.

2

Okay, I get what you want to do.

But it’s pretty confusing "como" you’re making.

Anyway, from what I understand what you’re wondering is:

How do I overwrite the prototype of a parent object, in the daughter class.

Before solving this, the ideal is for you to understand how to use Object Orientation correctly, because the example is very confusing and why some things are being done in X way instead of Y.

Anyway, there’s a big inconsistency in the code below.

Look at that:

Dia.prototype.saudacao = function() {
    var msg = this.saudacao();
    return msg + ' ' + this.newText;
}

You’re - trying to - overwrite a method and - without realizing it - creating an infinite loop, recursively.

Anyway, I understood what you were trying to do up there.

Switch to something like that:

Dia.prototype.saudacao = function() {
    return this.text + ' ' + this.name + ' ' + this.newText;
}

Now regarding the solution, the problem lies somewhere in the method heranca:

The way you are doing it is that it is causing all this trouble in the code, the overload of methods works normally if done the way "padrão".

The inheritance function should not be doing what we expected it to do, so it has become impossible to resolve this issue without greatly modifying the code you made.

I ended up redoing the code, basically it does the same thing and here it works well.

function Greet ( name , text ) {
    // Sobre o que falei acima de orientação a objetos, não vejo sentido do "nome" da pessoa estar nessa Classe. (só um exemplo)

    this._name = name ;
    this._text = text ;
    this._greet = function () {
        return this._text + ' ' + this._name ;
    }
}

function GoodDay ( greet ) {
    this.prototype = Greet ;

    Greet.call( this , 'Fulano? ' , 'Tudo bem, ' );

    this._greet = greet ;
}

GoodDay.prototype._greeting = function () {
    return this._text + ' ' + this._name + ' ' + this._greet ;
}

var hello = new GoodDay( 'Bom dia!' ) ;

alert( hello._greeting() ) ;

I broke my head too hard trying to keep this function heranca that you created, but I couldn’t solve with it.

Anyway, if you analyze the situation and think in an Object-Oriented way, you’ll see that it doesn’t make much sense to have a function that assigns inheritances between each class.

For example: a dog, he É an animal (this is immutable), no one needs to come and say that the dog is going to be an animal and that’s basically what you’re doing with this function heranca.

I don’t know if it’s very clear, but that’s +/- what I’m trying to explain.

  • Thank you for the answer. You’re right about what you said about the example. I tried to write a simple example considering the larger project, which is not about greetings. My code was based on what I learned from reading this text. Anyway, according to your code, I don’t have the _Greeting() method in the Father class, so there was no superscript in the Son class, do you agree? Since the question is about the superscript, I really appreciate your time, but I haven’t reached my goal.

  • @Leikovsk is absolutely right, it was a mistake of my attention, the truth is that the variable _Greet of the parent class should be called _Greeting, only that changing it the code back to not work, the night will take a look.

  • I totally disagree with the inheritance part. The way he did it is correct, and assign another function directly as prototype (this.prototype = Greet) is wrong and does not generate any inheritance.

  • Yes @bfavaretto, I believed it was due to inheritance, but I ended up passing beaten in variable _greeting, and that’s what made me think that the problem was that method, I apologize for that. But regarding the line this.prototype = Greet, it does generate inheritance, so much so that the text is properly filled at the end of everything.

  • I meant what is inherited in this.prototype = Greet has no effect on the result, even on your example. Because Greet has no method, then nothing is inherited from it. And said "wrong" because assign a construction function as a prototype of another breaks the prototype chain.

1

I rewrote the code thinking about the problem and using the past tips:

    var inheritance = function(father, child) {
	    var fatherCopy = Object.create(father.prototype);
    	child.prototype = fatherCopy;
    	child.prototype.constructor = child;
    }

    var Parent = function(msg) {
        this.text = msg;
    }
    Parent.prototype.message = function() {
    	return this.text;
    }
    var Oi = new Parent('Olá ');
    alert(Oi.message()); //Exibe "Olá"
    			
    var Child = function(nome) {
    	Parent.call(this, 'Olá ');
    	this.text2 = nome;
    }
    inheritance(Parent, Child);
    Child.prototype.message = function() {
    	return this.text + ' ' + this.text2;
    }
    			
    var Ai = new Child('Fulano');
    alert(Ai.message()); //Exibe "Olá Fulano"

Problem solved.

  • Show @Leikovsk! In the case then the solution was to define the prototype out of class?

  • @Fabianolothor for the problem presented, yes. But it does not solve the real problem that I have here. I believed that simplifying the problem would solve the main problem, but I was wrong. There are particularities that I did not describe in this problem here. I’m thinking of publishing another demand soon.

  • I’ve been curious since I read your question, to me, it doesn’t make sense that prototypes can be modified apenas if they are defined outside the class, there must be something that we are not seeing.

  • Post yes another question @Leikovsk :)

Browser other questions tagged

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