JavaScript:将继承的类添加到数组不起作用

Ale*_*der 5 javascript arrays inheritance prototype

我有一些JavaScript问题.我有以下代码:

<html>
<head>
<title>Test</title>
<script  type="text/javascript">
function Control(){
    var name;

    this.setName = function(newName){
        name = newName;
    };

    this.getName = function(){
        return name;
    };
}

function SpecializedControl(){
}
SpecializedControl.prototype = new Control();

function Form(){
    var formControls = [];

    this.addControl = function(control){
         formControls.push(control);

         alert(formControls[0].getName());
    };
}

var form = new Form();

var control1 = new SpecializedControl();
control1.setName("Control1");
form.addControl(control1);

var control2 = new SpecializedControl();
control2.setName("Control2");
form.addControl(control2);

</script>
</head>
<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

SpecializedControl继承自Control类.

Form类中的addControl函数只是将控件添加到数组中.

问题是,当我添加多个SpecializedControl时,数组中的值是一种覆盖,这意味着当我访问数组中的第一个项目时,应该是"Control1",我得到"Control2".Control1不再在数组中.

当我使用与Control对象相同的函数作为参数时,一切都按预期工作.

有人知道为什么会发生这种情况以及可以采取哪些措施来纠正这种情

小智 5

您的get/setName函数正在获取/设置构造函数name本地变量的值Control.

您调用该函数的唯一时间是创建一个实例作为prototype对象SpecializedControl.因此,每次setNameSpecializedControl实例调用时,都会更新该单个变量.

因此,由于get/setName引用该变量的方法位于所有SpecializedControl实例的原型链中,因此它们都将遵循相同的方式name.


setName,你应该做...

this.name = newName;
Run Code Online (Sandbox Code Playgroud)

getName,你应该做...

return this.name;
Run Code Online (Sandbox Code Playgroud)


Nat*_*all 5

数组中的值未被覆盖; 问题是两个控件共享同一个name变量.因为Control函数只执行一次,所以只name声明了一个变量.

你有两个主要的选择来解决这个问题.(1)创建name一个特定于每个单独控件的实例变量(例如this._name).(2)ControlSpecializedControl构造函数内部执行函数.(实际上,IMO,对于一个平衡和彻底的继承模型,你应该做一些这两种方法).

这是三个有效的解决方案.前两个分别使用选项(1)和(2).第三种方法结合了两种方法,就是我这样做的方式(但需要使用joi).

选项1:

function Control(){

    this.setName = function(newName){
        this._name = newName;
    };

    this.getName = function(){
        return this._name;
    };
}
Run Code Online (Sandbox Code Playgroud)

选项2:

function SpecializedControl(){
    Control.apply(this, arguments);
}
Run Code Online (Sandbox Code Playgroud)

选项3:

var Control = joi.Unit.sub(function() {

    function constructor() {
        this.base();
    }

    constructor.prototype = {
        '#name': null,
        setName: function(name) {
            this['#name'] = name;
        },
        getName: function() {
            return this['#name'];
        }
    };

    return constructor;

}());

var SpecializedControl = Control.sub(function() {

    function constructor() {
        this.base();
    }

    return constructor;

}());

var Form = joi.Unit.sub(function() {

    function constructor() {
        this.base();
        this['#formControls'] = [];
    }

    constructor.prototype = {
        '#formControls': null,
        addControl: function(control) {
            this['#formControls'].push(control);
            alert(this['#formControls'][0].getName());
        }
    };

    return constructor;

}());

var form = new Form();

var control1 = new SpecializedControl();
control1.setName("Control1");
form.addControl(control1);

var control2 = new SpecializedControl();
control2.setName("Control2");
form.addControl(control2);?
Run Code Online (Sandbox Code Playgroud)