简体   繁体   English

JavaScript继承-重叠的基类变量

[英]Javascript inheritance - overlapping base class variables

I am trying to create a custom javascript form validator. 我正在尝试创建一个自定义javascript表单验证程序。 I am starting by creating an input validator base class, and I am extending this base class to handle more specific input types. 我首先创建输入验证器基类,然后扩展此基类以处理更特定的输入类型。 For example, income and zipcode. 例如,收入和邮政编码。

Current structure is as follows: Base Class = InputValidator, Sub Classes: Income, ZipCode 当前结构如下:基本类= InputValidator,子类:收入,邮政编码

Things are working as expected when I create only one instance of Income. 当我仅创建一个实例实例时,事情按预期进行。 However, if I also create an instance of ZipCode, it appears to overwrite the base class of Income. 但是,如果我还创建ZipCode的实例,它似乎会覆盖Income的基类。 To see this in action, I have created a JSFiddle. 为了了解这一点,我创建了一个JSFiddle。 http://jsfiddle.net/tpdietz/wy274ymb/3/ http://jsfiddle.net/tpdietz/wy274ymb/3/

If you type in anything other than a digit for the annual income input, you should see a warning drop down above the income input. 如果您输入的数字不是数字,则应该在年薪输入上方看到警告。 This is what I want. 这就是我要的。 However, if you uncomment line 48 in the jsfiddle, re run it, and try the same thing. 但是,如果您取消注释jsfiddle中的第48行,请重新运行它,然后尝试相同的操作。 You will see that typing in something incorrect for the annual income, invokes the zip code warning. 您会看到输入不正确的年收入会触发邮政编码警告。 As expected, typing in something other than a digit for the zip code does the same thing. 不出所料,键入邮政编码以外的数字也可以完成相同的操作。

Here is how I am declaring the sub classes: 这是我声明子类的方式:

var Income = function (incomeElement, warningElement) {
    InputValidator.call(this, incomeElement, warningElement, isInteger);

    this.isValid = function() {
        return valid;
    }
}

var ZipCode = function (zipCodeElement, warningElement) {
    InputValidator.call(this, zipCodeElement, warningElement, isInteger);

    this.isValid = function() {
        return valid && ele.val().length < 6 && ele.val().length > 2;
    }
}

and here is how I declare the base class: 这是我如何声明基类的方法:

var InputValidator = function (element, warningElement, validatorIn) {
    this.name = name;
    ele = element;
    warning = warningElement;
    validator = validatorIn;
    valid = false;

    ele.keyup(function() {
        if(!validator($(this).val())) {
            showWarning();
            valid = false;
        } else {
            hideWarning();
            valid = true;
        }
    });

    function showWarning() {
        warning.slideDown();
    }
    function hideWarning() {
        warning.slideUp();
    }

}

Does anybody have any idea why this is happening? 有人知道为什么会这样吗? I thought I had a grasp on how this should work. 我以为我对这应该如何工作有所了解。

Thank you. 谢谢。

You need to declare all local variables with var in front of them so they are not implicit globals. 您需要在所有局部变量之前声明var ,以便它们不是隐式全局变量。 When you leave off var as in this: 当您像这样离开var时:

var InputValidator = function (element, warningElement, validatorIn) {
    this.name = name;
    ele = element;
    warning = warningElement;
    validator = validatorIn;
    valid = false;

You end up creating global variables. 您最终创建了全局变量。 Thus, when you create the second instance, all your instances are sharing the same globals and they all seem to overwrite each other. 因此,当您创建第二个实例时,所有实例共享相同的全局变量,并且它们似乎都相互覆盖。

Per-instance variables should either be declared with var as local to the constructor (and thus they will be private) or they should be assigned to this.propName like you are doing with this.name . 每个实例变量都应使用var声明为构造函数的本地变量(因此它们将是私有的),或者应像对this.name一样将其分配给this.propName

You can change your implementation to this: 您可以将实现更改为此:

var InputValidator = function (element, warningElement, validatorIn) {
    this.name = name;
    var ele = element;
    var warning = warningElement;
    var validator = validatorIn;
    var valid = false;

    ele.keyup(function() {
        if(!validator($(this).val())) {
            showWarning();
            valid = false;
        } else {
            hideWarning();
            valid = true;
        }
    });

    function showWarning() {
        warning.slideDown();
    }
    function hideWarning() {
        warning.slideUp();
    }

}

If you want all those variables to be local to the constructor and not accessible from outside the constructor. 如果您希望所有这些变量在构造函数中都是局部的,而不能从构造函数外部访问。


FYI, this is a great reason to run in Javascript's strict mode as it would flag this as an error. 仅供参考,这是在Javascript的严格模式下运行的重要原因,因为它将标记为错误。

var InputValidator = function (element, warningElement, validatorIn) {
    "use strict";
    this.name = name;
    ele = element;  // <== This is an error in strict mode, since ele is not declared

Note, there is no reason to take an argument from the constructor and simply assign it to a new local variable. 注意,没有理由从构造函数中获取参数,只需将其分配给新的局部变量即可。 You can just reference the named argument the same as you would a local variable. 您可以引用命名参数,就像引用局部变量一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM