【问题标题】:How to call parent class' method from a subclass in JavaScript so that parent's local variables would be accessible?如何从 JavaScript 中的子类调用父类的方法,以便可以访问父类的局部变量?
【发布时间】:2013-08-21 16:06:11
【问题描述】:

我正在使用 JavaScript 中的类继承方法之一(在我正在修改的代码中使用),但不明白如何将子类中方法的附加功能附加到相应父类的功能方法已经有了;换句话说,我想用一种方法覆盖子类中父类的方法,除了它自己的子类特定的东西外,它的作用与父类的方法相同。所以,我试图从孩子的方法中调用父母的方法,但这有可能吗?

代码在这里:http://jsfiddle.net/7zMnW/。请打开开发控制台查看输出。

代码也在这里:

function MakeAsSubclass (parent, child)
{
    child.prototype = new parent;   // No constructor arguments possible at this point.
    child.prototype.baseClass = parent.prototype.constructor;
    child.prototype.constructor = child;

    child.prototype.parent = child.prototype; // For the 2nd way of calling MethodB.
}

function Parent (inVar)
{
    var parentVar = inVar;

    this.MethodA = function () {console.log("Parent's MethodA sees parent's local variable:", parentVar);};
    this.MethodB = function () {console.log("Parent's MethodB doesn't see parent's local variable:", parentVar);};
}

function Child (inVar)
{
    Child.prototype.baseClass.apply(this, arguments);

    this.MethodB = function ()
    {
        console.log("Child's method start");
        Child.prototype.MethodB.apply(this, arguments); // 1st way
        this.parent.MethodB.apply(this, arguments); // 2 2nd way
        console.log("Child's method end");
    };
}

MakeAsSubclass(Parent, Child);

var child = new Child(7);
child.MethodA();
child.MethodB();

【问题讨论】:

  • 不,您看不到父级局部变量。你继承了父原型链,而不是它们的本地状态。

标签: javascript oop inheritance superclass


【解决方案1】:

我建议再次使用这样的私有实例值属性,因为它会弄乱原型。需要访问私有实例变量的函数(每个实例都有自己的私有值)不能放在原型上,所以你不能真正使用它。

这是您的代码的工作方式(但我自己不会这样做):

var Parent = function(){
  var private=22;
  this.showPrivate=function(){
    console.log(private);
  }
}
var Child=function(){Parent.call(this)};
// the following is only usefull if you have functions
// on the parent prototype that don't use privates
Child.prototype=Object.create(Parent.prototype);
// Child.prototype.constructor would now point to Parent
// it's not needed most of the time but you can fix that
Child.prototype.constructor=Child;

var c = new Child();
c.showPrivate();

以下是使用“私有”函数的方法:

var Parent = function(name){
  //public instance variable
  this.name=name;
}
Parent.prototype=function(){
  // privates on the prototype (shared among instances)
  var privateFunction=function(me){
    console.log("private function called in:"+me.name);
    console.log("shared in "+me.name
      +" is now:"+shared+" setting it to 'changed'");
    shared="Changed";
  }
  // private shared value
  var shared="Parent"
  return{
    constructor:Parent,
    publicFn:function(){
     privateFunction(this); 
    }
  };
}();

var Child=function(name){Parent.call(this,name)};
Child.prototype=Object.create(Parent.prototype);
Child.prototype.constructor=Child;

var c = new Child("child1");
var c2 = new Child("child2");
c.publicFn();
c2.publicFn();//shared is already changed by 'child1'

更多关于构造函数的信息here

【讨论】:

  • 感谢私有函数和私有静态/共享变量的参考!但是关于私有实例值:您的示例与我的示例到底有什么不同? “showPrivate”函数看起来很像我的“MethodA”,可以访问局部变量。这是我遇到问题的“方法B”。
  • @Janis 我不知道,不知道你的代码应该做什么。根据您对问题的描述,我尝试发布显示如何覆盖父函数的代码。使用私有实例值属性(构造函数体中的所有内容)的示例我猜这没有显示为覆盖,因为我从不使用它。我猜你可以保存父函数,然后在子体中调用 Parent.call(this) 之前调用它。
【解决方案2】:

变量var parentVar = inVar; 是一个局部和私有变量,仅在Parent() 函数中可用,并且仅对在同一范围(Parent()) 中定义的函数可见。

我认为这里最好的方法是修改 Parent 类,使 parentVar 不是私有的,而是公共的:

function Parent(inVar) {

    this.parentVar = inVar;

}

【讨论】:

    【解决方案3】:

    不,您看不到父级局部变量。您继承父母原型链,而不是他们的本地状态。在您的情况下,您将父函数应用于不包含状态的子对象。

    apply(this,...)
    

    表示您将函数绑定到 this 的当前值。当您从子对象调用方法 b 时,它会绑定到子对象,因此不在包含父值的闭包内操作。

    【讨论】:

    • 但是 Parent 的 MethodA(从子对象调用)确实看到了变量。我猜这是因为它是在其构造函数中为孩子重新创建的。但是,MethodB 没有。
    • 您在父对象上调用 A。您在子对象上调用 B 。如果你用 apply(this) 调用 A,它也会失败
    • 好吧,我觉得很奇怪。 :) 我的意思是,我是 child.MethodA();,但事实证明我实际上是在父对象上调用 MethodA!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    相关资源
    最近更新 更多