使用JavaScript原型的调用方法

是否有可能从JavaScript中的原型方法调用基本方法,如果它被覆盖?

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 } }; 

我不明白你到底在做什么,但是通常按照下面这些方法来实现对象特定的行为:

 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...*/); } 

那么做一个方法就是保存基本方法,然后从overriden方法调用它,像这样

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

我担心你的榜样不符合你的想法。 这部分:

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

覆盖的定义

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

由于新创build的对象已经具有“do”属性,因此不会查找原型链。

Javascript中的传统forms的inheritance是困难的,很难把握。 我build议使用Douglas Crockfords简单的inheritance模式。 喜欢这个:

 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 

在我看来,处理对象,构造函数和inheritance的更清晰的方式。 你可以阅读更多在Crockfords Javascript:好的部分 。

我知道这篇文章是从4年前,但由于我的C#背景,我正在寻找一种方法来调用基类,而不必指定类名,而是通过子类上的属性获得它。 所以我唯一的改变就是克里斯多弗的回答

由此:

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

对此:

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

如果你定义一个这样的函数(使用OOP)

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

有两种方法可以调用一个原型函数:1)创build一个实例并调用对象函数:

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

另一种方法是… 2)直接从原型调用函数:

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

替代 :

 // 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); } 
以下是为我工作的解决scheme。 它使用Object.getPrototypeOfTestA超级有getName
 TestB是一个覆盖getName但是也有的孩子
调用getName超版本以及子版本的 getBothNames
 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(); }; } 

如果我理解正确,你希望Basefunction始终被执行,而其中的一部分应该留给实现。

你可能会得到' 模板方法 'devise模式的帮助。

 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 */ } 

如果你知道你的超级class的名字,你可以做这样的事情:

 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(); 

这将打印

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

如预期。

ES5的另一种方法是使用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() 

不,您需要在构造函数中给do函数和原型不同名称中的do函数。

另外,如果你想覆盖所有的实例 ,而不仅仅是一个特殊的实例,这个可能会有所帮助。

 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(); 

结果:

 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();