Método de chamada usando protótipo de JavaScript

É possível chamar o método base de um método protótipo em JavaScript se ele foi substituído?

MyClass = function(name){ this.name = name; this.do = function() { //do somthing } }; MyClass.prototype.do = function() { if (this.name === 'something') { //do something new } else { //CALL BASE METHOD } }; 

Eu não entendi exatamente o que você está tentando fazer, mas normalmente implementar um comportamento específico do object é feito ao longo destas linhas:

 function MyClass(name) { this.name = name; } MyClass.prototype.doStuff = function() { // generic behaviour } var myObj = new MyClass('foo'); var myObjSpecial = new MyClass('bar'); myObjSpecial.doStuff = function() { // do specialised stuff // how to call the generic implementation: MyClass.prototype.doStuff.call(this /*, args...*/); } 

Bem, uma maneira de fazer isso seria salvando o método base e, em seguida, chamando-o do método overriden, assim

 MyClass.prototype._do_base = MyClass.prototype.do; MyClass.prototype.do = function(){ if (this.name === 'something'){ //do something new }else{ return this._do_base(); } }; 

Receio que o seu exemplo não funcione do jeito que você pensa. Esta parte:

 this.do = function(){ /*do something*/ }; 

substitui a definição de

 MyClass.prototype.do = function(){ /*do something else*/ }; 

Como o object recém-criado já tem uma propriedade “do”, ele não procura a cadeia de protótipos.

A forma clássica de inheritance em Javascript é inadequada e difícil de entender. Eu sugeriria usar o padrão de inheritance simples de Douglas Crockfords. Como isso:

 function my_class(name) { return { name: name, do: function () { /* do something */ } }; } function my_child(name) { var me = my_class(name); var base_do = me.do; me.do = function () { if (this.name === 'something'){ //do something new } else { base_do.call(me); } } return me; } var o = my_child("something"); o.do(); // does something new var u = my_child("something else"); u.do(); // uses base function 

Na minha opinião, uma maneira muito mais clara de manipulação de objects, construtores e inheritance em javascript. Você pode ler mais em Crockfords Javascript: The good parts .

Eu sei que este post é de 4 anos atrás, mas por causa do meu plano de fundo c # eu estava procurando uma maneira de chamar a class base sem ter que especificar o nome da class, mas obtê-lo por uma propriedade na subclass. Então, minha única mudança para a resposta de Christoph seria

A partir disso:

 MyClass.prototype.doStuff.call(this /*, args...*/); 

Para isso:

 this.constructor.prototype.doStuff.call(this /*, args...*/); 

se você definir uma function como esta (usando OOP)

 function Person(){}; Person.prototype.say = function(message){ console.log(message); } 

Há duas maneiras de chamar uma function protótipo: 1) faça uma instância e chame a function de object:

 var person = new Person(); person.say('hello!'); 

e o outro jeito é … 2) está chamando a function diretamente do protótipo:

 Person.prototype.say('hello there!'); 

Uma alternativa :

 // shape var shape = function(type){ this.type = type; } shape.prototype.display = function(){ console.log(this.type); } // circle var circle = new shape('circle'); // override circle.display = function(a,b){ // call implementation of the super class this.__proto__.display.apply(this,arguments); } 

Esta solução usa Object.getPrototypeOf

TestA é super que tem getName

TestB é um filho que sobrescreve getName mas também tem getBothNames que chama a getBothNames de getName assim como a versão child

 function TestA() { this.count = 1; } TestA.prototype.constructor = TestA; TestA.prototype.getName = function ta_gn() { this.count = 2; return ' TestA.prototype.getName is called **'; }; function TestB() { this.idx = 30; this.count = 10; } TestB.prototype = new TestA(); TestB.prototype.constructor = TestB; TestB.prototype.getName = function tb_gn() { return ' TestB.prototype.getName is called ** '; }; TestB.prototype.getBothNames = function tb_gbn() { return Object.getPrototypeOf(TestB.prototype).getName.call(this) + this.getName() + ' this object is : ' + JSON.stringify(this); }; var tb = new TestB(); console.log(tb.getBothNames()); 
 function NewClass() { var self = this; BaseClass.call(self); // Set base class var baseModify = self.modify; // Get base function self.modify = function () { // Override code here baseModify(); }; } 

Se bem entendi, você quer que a funcionalidade Base seja sempre executada, enquanto uma parte dela deve ser deixada para implementações.

Você pode ser ajudado pelo padrão de design ‘ método de modelo ‘.

 Base = function() {} Base.prototype.do = function() { // .. prologue code this.impldo(); // epilogue code } // note: no impldo implementation for Base! derived = new Base(); derived.impldo = function() { /* do derived things here safely */ } 

Se você conhece sua superclass por nome, você pode fazer algo assim:

 function Base() { } Base.prototype.foo = function() { console.log('called foo in Base'); } function Sub() { } Sub.prototype = new Base(); Sub.prototype.foo = function() { console.log('called foo in Sub'); Base.prototype.foo.call(this); } var base = new Base(); base.foo(); var sub = new Sub(); sub.foo(); 

Isto irá imprimir

 called foo in Base called foo in Sub called foo in Base 

como esperado.

Outra maneira com o ES5 é percorrer explicitamente a cadeia de protótipos usando Object.getPrototypeOf(this)

 const speaker = { speak: () => console.log('the speaker has spoken') } const announcingSpeaker = Object.create(speaker, { speak: { value: function() { console.log('Attention please!') Object.getPrototypeOf(this).speak() } } }) announcingSpeaker.speak() 

Não, você precisaria dar a function do no construtor e a function do nos nomes diferentes do protótipo.

Além disso, se você quiser replace todas as instâncias e não apenas essa instância especial, esta pode ajudar.

 function MyClass() {} MyClass.prototype.myMethod = function() { alert( "doing original"); }; MyClass.prototype.myMethod_original = MyClass.prototype.myMethod; MyClass.prototype.myMethod = function() { MyClass.prototype.myMethod_original.call( this ); alert( "doing override"); }; myObj = new MyClass(); myObj.myMethod(); 

resultado:

 doing original doing override 
 function MyClass() {} MyClass.prototype.myMethod = function() { alert( "doing original"); }; MyClass.prototype.myMethod_original = MyClass.prototype.myMethod; MyClass.prototype.myMethod = function() { MyClass.prototype.myMethod_original.call( this ); alert( "doing override"); }; myObj = new MyClass(); myObj.myMethod();