Javascript子类,超级构造函数和使用自定义扩展会丢失基类方法 [英] Javascript sub classing, super constructors and using custom extend loses base class methods

查看:72
本文介绍了Javascript子类,超级构造函数和使用自定义扩展会丢失基类方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在另一个关于是否调用超级构造函数还是使用原型链的问题中,一个用户提供的答案似乎很明智,但是当我在具有多层继承的解决方案中实现它时,它对我却不起作用.

In another SO question about whether to call a super-constructor or use the prototype chain the answer provided by one of the users seemed sensible but didn't work for me when I implemented it on my solution which has multiple layers of inheritance.

这是我指的答案: https://stackoverflow.com/a/4389429/392591

因此,我使用此自定义扩展方法创建了一个jsFiddle来说明问题: https://jsfiddle.net /68q7yghv/
我在底部添加了jsFiddle代码.

So I've created a jsFiddle using this custom extend method to illustrate the problem: https://jsfiddle.net/68q7yghv/
I've added the jsFiddle code at the bottom.

在我的测试中,我创建了一个从baseClass到subSubSubClass的4层类继承结构,每个结构(baseClass除外)都使用'extend'方法继承前一个子类.当您按下测试按钮时,我将打印出 class .baseClassMethod,以查看是否找到了它,但只为基类找到了它.

In my test I've created a 4 tier class inheritance structure from baseClass through to subSubSubClass each of which (except the baseClass) use the 'extend' method to inherit from the previous sub-class. When you hit the test button I'm printing out class.baseClassMethod to see if it finds it, but it only finds it for the base class.

您应该看到以下结果: 函数(){this.output + ="baseClassMethod"; }
未定义
未定义
未定义

You should see the following results: function () { this.output += "baseClassMethod"; }
undefined
undefined
undefined

是否可能是因为对超级构造函数的调用与'this'上下文混淆了?

function extend(baseClass, subClass) {
  var originalPrototype = subClass.prototype;
  subClass.prototype = Object.create(baseClass.prototype);
  for (var key in originalPrototype) {
    subClass.prototype[key] = originalPrototype[key];
  }
  subClass.prototype.constructor = subClass;
  Object.defineProperty(subClass.prototype, 'constructor', {
    enumerable: false,
    value: subClass
  });
};

var baseClass = function() {
  this.output = "Base: ";
  this.toggleWizardHandlers = [];
  this.baseClassMethod = function() {
    this.output += "baseClassMethod";
  };
};

baseClass.prototype.on = function(eventName, handler) {
  switch (eventName.toLowerCase()) {
    case "togglewizards":
      return this.toggleWizardHandlers.push(handler);
      break;
  }
};

baseClass.prototype.toggleWizards = function(newWizard, newStepIndex) {
  var handler, i, len, ref;
  ref = this.toggleWizardHandlers;
  for (var i = 0; i < ref.length; i++) {
    handler = ref[i];
    setTimeout(handler, 0, newWizard, newStepIndex);
  }
};

var subClass = function() {
  baseClass(this);
};
extend(baseClass, subClass);

var subSubClass = function() {
  subClass(this);
};
extend(subClass, subSubClass);

var subSubSubClass = function() {
  subSubClass(this);
};
extend(subSubClass, subSubSubClass);

var manager = function(settings) {

  this.log = function(message) {
    $("#log").html($("#log").html() + "<br />" + message);
  };
  this.clearLog = function() {
    $("#log").html("");
  };

  this.testBaseClass = new baseClass();
  this.testSubClass = new subClass();
  this.testSubSubClass = new subSubClass();
  this.testSubSubSubClass = new subSubSubClass();

  //test.on("toggleWizards", function(param) {    that.log(param);  });
};

$(function() {
  var manage = new manager("");

  $("#btn").click(function() {
    manage.log("start test");
    manage.clearLog();

    try {
      manage.log(manage.testBaseClass.baseClassMethod);
    } catch (e) {
      manage.log(e);
    }

    try {
      manage.log(manage.testSubClass.baseClassMethod);
    } catch (e) {
      manage.log(e);
    }

    try {
      manage.log(manage.testSubSubClass.baseClassMethod);
    } catch (e) {
      manage.log(e);
    }

    try {
      manage.log(manage.testSubSubSubClass.baseClassMethod);
    } catch (e) {
      manage.log(e);
    }
  });

});

推荐答案

您的原型继承正在运行,您可以尝试在所有实例上访问ontoggleWizards.

Your prototype inheritance is working, you can try to access on or toggleWizards on all your instances.

尽管您在构造函数中的超级调用缺少关键部分: .call .没有它,您将传递this作为第一个参数,而不是作为this参数.没有这个,您的基类将无法初始化子类实例上的任何属性:

Your super calls in the constructors lack a crucial part though: .call. Without it, you are passing this for the first parameter, not as the this argument. Your base class is not able to initialise any properties on the subclass instance without this:

function subClass() {
    baseClass.call(this);
//            ^^^^
}

这篇关于Javascript子类,超级构造函数和使用自定义扩展会丢失基类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆