具有意外行为的JavaScript继承 [英] JavaScript inheritance with unexpected behaviour

查看:161
本文介绍了具有意外行为的JavaScript继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何解决下列JavaScript问题:

I don't know how to solve the following JavaScript problem:

function A() {
    var numbers = [];

    this.addNumber = function(number) {
        numbers.push(number);
    }

    this.getNumbers = function() {
        return numbers;
    }
}

A.prototype.alertNumbers = function() {
    var numbers = this.getNumbers();
    var length = numbers.length;
    var number;
    var numbersString = "";
    for (var i = 0; i < length; i++) {
        number = numbers[i];
        numbersString += " " + number;
    }
    alert(numbersString);
}

B.prototype = new A();

function B() {
    this.addNumber(1);
    this.addNumber(2);
}

var b = new B();
b.alertNumbers();

var otherB = new B();
otherB.alertNumbers();

工作代码在这里: http://jsfiddle.net/pFxse/

我期望otherB.alertNumbers();还显示1 2而不是1 2 1 2。

I'm expecting that otherB.alertNumbers(); also shows "1 2" and not "1 2 1 2".

感谢

推荐答案

问题是,当你这样做:

B.prototype = new A();

您将B.prototype设置为A的实例,因此B.prototype将有2个函数

You set B.prototype to be an instance of A, thus B.prototype will have 2 functions that access a private variable numbers.

现在,当您访问(new B())。addNumber()将使用原型中的函数,从而从原型中使用数组。所有实例将使用该数组。所有实例都会推送到该数组。

Now when you access (new B()).addNumber(), you will use the function from the prototype and thus the array from the prototype. All instances will use that array. All instances will push to that array.

要修复它,就足够了:

function B() {
    A.call(this); // call superclass
    this.addNumber(1);
    this.addNumber(2);
}

通过调用B的构造函数中的超类, B的实例,以及包围该变量的2个函数。每个实例将使用其特定的addNumbers函数,该函数使用其特定的闭包数组。

By calling the superclass in B's constructor, you have created a numbers variable for each instance of B, along with 2 functions which enclose over that variable. Each instance will use its specific addNumbers function which uses its specific closured array.

也可以简化:

B.prototype = Object.create(A.prototype);

而不是创建一个类型A的新对象并将其设置为B的原型, B的原型直接从A的原型继承。你仍然有在A的构造函数中定义的方法,因为你调用了超类。优点是,现在你不再为每个子类创建A的实例(或许更重要),现在你可以传递参数到构造函数:

Instead of creating a new object of type A and setting that to the prototype of B, you set the prototype of B to inherit directly from the prototype of A. You still have methods defined in A's constructor because you called the superclass. The advantage is that now you no longer create instances of A for each subclass and (perhaps more important) you can now pass arguments to the constructor:

function A(name) {
  this.name = name;
}

function B(name) {
  A.call(this, 'B' + name);
}
B.prototype = Object.create(A.prototype);

您的继承模型中不能有此方案。

You can't have this scenario in your inheritance model.

这篇关于具有意外行为的JavaScript继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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