使用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.getPrototypeOf 。 TestA超级有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();