有没有办法将字段设置在子对象范围内,同时可以从父对象访问?

时间:2011-09-08 18:10:33

标签: javascript oop inheritance scope prototypal-inheritance

我在JavaScript中使用OOP做一些经验。我的目标是拥有一个父对象,该对象包含从该父对象继承的其他几个对象共有的方法。事实上,我希望父对象的方法能够读取孩子们的字段。

我使用以下函数进行继承:

Function.prototype.inherits=function(obj){this.prototype=new obj();}

这些是一些示例对象:

function Genetic(c){
    this.code=c;
}
//My 'parent object':
function Animal(){
    this.getCode=function(){
        return(genetic.code);
    }
}
g=new Genetic('test');
function Dog(){
    genetic=g;
}
Dog.inherits(Animal);
g=new Genetic('foo');
function Cat(){
    genetic=g;
}
Cat.inherits(Animal);

d=new Dog();
c=new Cat();

现在,我希望d.getCode()返回'test'c.getCode()返回'foo'。问题是,都返回'foo'。变量genetic位于Animal范围内,而不在Dog / Cat范围内。这意味着每当我创建一个继承自Animal的新对象时,genetic变量都将被覆盖。证明:

function Bla(){}
Bla.inherits(Animal);
bla=new Bla()
bla.getCode() //Returns 'foo'

我可以将genetic变量设置为DogCat的私有变量,其中包含var:

function Dog(){
    var genetic=g;
}

问题是,由于genetic现在对Dog是私有的,Animal对象无法访问它,导致整个继承毫无意义。

你有没有办法解决这个问题?

编辑:此外,我希望gentic是私有的,因此无法在Dog / Cat个实例中对其进行修改。

1 个答案:

答案 0 :(得分:3)

  

变量'genetic'在动物范围内,而不在Dog / Cat范围内。

不,genetic 全球。整个应用程序中只存在一个genetic变量。使它成为对象的属性。

此外,更好的继承方式如下:

function inherits(Child, Parent) {
    var Tmp = function(){};
    TMP.prototype = Parent.prototype;
    Child.prototype = new Tmp();
    Child.prototype.constructor = Child;
}

然后你可以让父构造函数接受参数,而不必重复代码:

//My 'parent object':
function Animal(g){
    this.genetic = g;
}

Animal.prototype.getCode = function() {
    return this.genetic.code;
}

function Dog(){
    Animal.apply(this, arguments);
}
inherits(Dog, Animal);

function Cat(){
    Animal.apply(this, arguments);
}
inherits(Cat, Animal);

var d = new Dog(new Genetic('test'));
var c = new Cat(new Genetic('foo'));

我会建议document your code properly,而是遵循明确的原型/继承链,而不是尝试做一些不是为此设计的语言。

但是,使用上面给出的inherits函数,您可以执行以下操作:

function Animal(g){
    var genetic = g

    this.getCode = function(){
        return genetic.code ;
    }
}

其余代码保持不变。然后,您拥有“私有”变量,每个实例都有自己的getCode函数。

修改:这不允许您在分配给geneticDog的任何功能中访问Cat,除非您同时保留对该值的引用他们的建设者。