[英]Calling method using JavaScript prototype
如果它被覆盖,是否可以从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...*/);
}
那么一种方法是保存基本方法,然后从override方法调用它,就像这样
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*/ };
由于新创建的对象已经具有“do”属性,因此它不会查找原型链。
Javascript中经典的继承形式很笨拙,难以掌握。 我建议使用Douglas Crockfords简单的继承模式。 像这样:
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
在我看来,在javascript中处理对象,构造函数和继承的更清晰的方法。 你可以在Crockfords Javascript中阅读更多内容:好的部分 。
我知道这篇文章来自4年前,但由于我的C#背景,我一直在寻找一种方法来调用基类,而不必指定类名,而是通过子类上的属性获取它。 所以我对Christoph的答案唯一的改变就是
由此:
MyClass.prototype.doStuff.call(this /*, args...*/);
对此:
this.constructor.prototype.doStuff.call(this /*, args...*/);
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();
};
}
如果你定义这样的函数(使用OOP)
function Person(){};
Person.prototype.say = function(message){
console.log(message);
}
有两种方法可以调用原型函数:1)创建一个实例并调用对象函数:
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);
}
此解决方案使用Object.getPrototypeOf
TestA
是具有getName
超级
TestB
是一个覆盖getName
的子代,但是也有getBothNames
调用getName
的super
版本以及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());
如果我理解正确,您希望始终执行Base功能,而其中一部分应该留给实现。
您可能会通过' 模板方法 '设计模式获得帮助。
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 */ }
如果你知道你的超级名字,你可以这样做:
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()
此外,如果要覆盖所有实例而不仅仅是那个特殊实例,那么这个实例可能会有所帮助。
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
不,你需要在构造函数中给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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.