如何从javascript的子类中调用父方法?

问题描述 投票:144回答:8

我花了最后几个小时试图找到解决我的问题的方法,但这似乎毫无希望。

基本上,我需要知道如何从子类中调用父方法。到目前为止,我尝试过的所有工作都以无法工作或覆盖父方法而告终。

我正在使用以下代码在javascript中设置OOP:

// SET UP OOP
// surrogate constructor (empty function)
function surrogateCtor() {}

function extend(base, sub) {
    // copy the prototype from the base to setup inheritance
    surrogateCtor.prototype = base.prototype;
    sub.prototype = new surrogateCtor();
    sub.prototype.constructor = sub;
}

// parent class
function ParentObject(name) {
    this.name = name;
}
// parent's methods
ParentObject.prototype = {
    myMethod: function(arg) {
        this.name = arg;
    }
}

// child
function ChildObject(name) {
    // call the parent's constructor
    ParentObject.call(this, name);
    this.myMethod = function(arg) {
        // HOW DO I CALL THE PARENT METHOD HERE?
        // do stuff
    }
}

// setup the prototype chain
extend(ParentObject, ChildObject);

我需要先调用父方法,然后在子类中向它添加更多内容。

在大多数OOP语言中,就像调用parent.myMethod()一样简单但我真的无法掌握它在javascript中的完成方式。

非常感谢您的帮助,谢谢!

我花了最后几个小时试图找到解决我的问题的方法,但这似乎毫无希望。基本上,我需要知道如何从子类中调用父方法。我所有的东西...

javascript oop methods parent
8个回答
187
投票

这是如何完成的:ParentClass.prototype.myMethod();


139
投票

ES6样式允许您使用新功能,例如super关键字。当您使用ES6类语法时,super关键字全部与父类上下文有关。作为一个非常简单的示例,签出:


4
投票

在多重继承级别的情况下,此函数可以用作其他语言的super()方法。 Here is a demo fiddle,通过一些测试,您可以像这样使用它,在方法内部使用:call_base(this, 'method_name', arguments);


4
投票

为了执行此操作,您不受限于ES6的Class抽象。可以通过__proto__属性访问父构造函数的原型方法(我很确定会有JS编码员抱怨它已贬值),该属性已贬值,但同时发现它实际上是实现以下目的的必要工具:分类需求(尤其是Array子分类需求)。因此,尽管__proto__属性在我所知道的所有主要JS引擎中仍然可用,但ES6在其之上引入了Object.getPrototypeOf()功能。 Object.getPrototypeOf()抽象中的super()工具是这种语法的语法糖。


2
投票

基于道格拉斯·克罗克福德思想的东西怎么样:


2
投票

这是子对象使用JavaScript的原型链访问父级属性和方法的好方法,并且与Internet Explorer兼容。 JavaScript在原型链中搜索方法,我们希望孩子的原型链看起来像这样:


0
投票

虽然您可以通过父级的原型调用父级方法,但是您需要传递当前的子级实例以使用//Parent constructor function ParentConstructor(firstName){ //add parent properties: this.parentProperty = firstName; } //add 2 Parent methods: ParentConstructor.prototype.parentMethod = function(argument){ console.log( "Parent says: argument=" + argument + ", parentProperty=" + this.parentProperty + ", childProperty=" + this.childProperty ); }; ParentConstructor.prototype.commonMethod = function(argument){ console.log("Hello from Parent! argument=" + argument); }; //Child constructor function ChildConstructor(firstName, lastName){ //first add parent's properties ParentConstructor.call(this, firstName); //now add child's properties: this.childProperty = lastName; } //insert Parent's methods into Child's prototype chain var rCopyParentProto = Object.create(ParentConstructor.prototype); rCopyParentProto.constructor = ChildConstructor; ChildConstructor.prototype = rCopyParentProto; //add 2 Child methods: ChildConstructor.prototype.childMethod = function(argument){ console.log( "Child says: argument=" + argument + ", parentProperty=" + this.parentProperty + ", childProperty=" + this.childProperty ); }; ChildConstructor.prototype.commonMethod = function(argument){ console.log("Hello from Child! argument=" + argument); // *** call Parent's version of common method ParentConstructor.prototype.commonMethod(argument); }; //create an instance of Child var child_1 = new ChildConstructor('Albert', 'Einstein'); //call Child method child_1.childMethod('do child method'); //call Parent method child_1.parentMethod('do parent method'); //call common method child_1.commonMethod('do common method');callapply方法。 bind方法将创建一个新函数,因此我不建议您在只考虑一次调用的情况下关注性能。


0
投票

对于多层原型查找,有一种更简单,更紧凑的解决方案,但它需要function proxy(context, parent){ var proto = parent.prototype; var list = Object.getOwnPropertyNames(proto); var child = {}; for(var i=0; i<list.length; i++){ var key = list[i]; // Create only when child have similar method name if(context[key] !== proto[key]){ child[key] = context[key]; context[key] = function(){ context.super = proto[key]; return child[key].apply(context, arguments); } } } } // ========= The usage would be like this ========== class Parent { first = "Home"; constructor(){ console.log('Parent created'); } add(arg){ return this.first + ", Parent "+arg; } } class Child extends Parent{ constructor(b){ super(); proxy(this, Parent); console.log('Child created'); } // Comment this to call method from parent only add(arg){ return this.super(arg) + ", Child "+arg; } } var family = new Child(); console.log(family.add('B'));支持。用法:Proxy,例如,假设使用方法SUPER(<instance>).<method>(<args>)的两个类AB extends Am

© www.soinside.com 2019 - 2024. All rights reserved.