Javascript原型继承私有方法

时间:2015-01-21 08:12:07

标签: javascript inheritance prototype

我一直在用私人"私人"来调查多个继承权。变量在每个"类"在JavaScript中,但遇到这种奇特的奇点:

function Ammo() {
    var a = 0;
    this.get_ammo = function() {
        return a;
    };

    this.add_to_ammo = function() {
        a = a+1
        return a;
    };

    this.clean_ammo = function() {
        return a=0;
    }
}

function Weapon() {
    var a =0;
}

function Gun() {
    var a = 0;
    this.fire = function(){
        console.log("Bang");
    }
}

Weapon.prototype = new Ammo();
Weapon.prototype.constructor  = Weapon();

Gun.prototype = new Weapon();
Gun.prototype.constructor = Gun();

var a = new Ammo();
var w = new Weapon();
var g = new Gun();

a.add_to_ammo()
a.add_to_ammo()
a.add_to_ammo()
console.log(w.get_ammo())
// At this point I get 0, as expected. But after
w.add_to_ammo()
w.add_to_ammo()
w.add_to_ammo()
console.log(g.get_ammo())
// But here I get 3!

有人可以解释为什么我在

之后得到3分
console.log(g.get_ammo())

我认为对象a,w,g是独立的,他们的领域也是如此。

我也发现如果我改变了

var a = 0;

this.a = 0;

我得到预期的结果。对象的字段未绑定到其父节点字段。

2 个答案:

答案 0 :(得分:4)

{p> var aAmmo中定义,但其他构造函数中的var a绝对没有任何内容。调用方法时正在修改的a,无论哪个实例始终与a中的闭包中捕获的Ammo相同。

你不能在JavaScript中拥有你想要的私有变量,那没关系。最常见的方法是将变量设为public,并在其前面添加下划线,将其标记为“internal”:

function Ammo() {
  this._ammo = 0;
}

然后将方法添加到prototype并使用this._ammo来引用该变量:

Ammo.prototype.getAmmo = function() {
  return this._ammo
}

然后您可以使用Object.create继承:

Weapon.prototype = Object.create(Ammo.prototype);

在构造函数“call super”中:

function Weapon() {
  Ammo.call(this) // gets own "_ammo"
}

此外,您没有正确设置构造函数。你应该分配一个函数,而不是调用它:

Weapon.prototype.constructor = Weapon;
Gun.prototype.constructor = Gun;

答案 1 :(得分:0)

我没有足够的回复点来评论@elclanrs的答案,所以请原谅我。

他的回答是正确的,但最相关的信息是最后一次

  

此外,您没有正确设置构造函数。你应该分配一个函数,而不是调用它:

Weapon.prototype.constructor = Weapon;
Gun.prototype.constructor = Gun;

在函数闭包范围内声明的变量是私有的!但是,你从来没有正确地实例化你的子类对象,所以你有一个frankenstein的事情:一个对象,很多身体部位。

除此之外,你的代码没有任何本质上的错误,它不是人们通常写的方式" Classes"我不会在这个问题的背景下解释原因。