Javascript 是否有一种方法可以将字段设置为在子对象范围内,同时可以从父对象访问?

Javascript 是否有一种方法可以将字段设置为在子对象范围内,同时可以从父对象访问?,javascript,oop,inheritance,scope,prototypal-inheritance,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': fun

我正在用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
范围内。这意味着每当我创建一个从
动物
继承的新对象时,
遗传
变量将被覆盖。证明:

function Bla(){}
Bla.inherits(Animal);
bla=new Bla()
bla.getCode() //Returns 'foo'
我可以使用var将
genetic
变量设置为
Dog
Cat
的私有变量:

function Dog(){
    var genetic=g;
}
问题是,由于
genetic
现在是
Dog
的私有对象,因此
动物
对象无法访问它,从而使整个遗传变得毫无意义

你有办法解决这个问题吗

编辑:另外,我希望
gentic
是私有的,这样就不能在
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'));
我建议您遵循一个清晰的原型/继承链,而不是尝试做一些语言不是为之设计的事情

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

function Animal(g){
    var genetic = g

    this.getCode = function(){
        return genetic.code ;
    }
}
代码的其余部分保持不变。然后您就有了“private”变量,每个实例都有自己的
getCode
函数

编辑:这将不允许您访问分配给
Dog
Cat
的任何函数中的
genetic
,除非您还在其构造函数中保留对值的引用

“遗传”变量在动物范围内,而不在狗/猫范围内

不,
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'));
我建议您遵循一个清晰的原型/继承链,而不是尝试做一些语言不是为之设计的事情

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

function Animal(g){
    var genetic = g

    this.getCode = function(){
        return genetic.code ;
    }
}
代码的其余部分保持不变。然后您就有了“private”变量,每个实例都有自己的
getCode
函数


编辑:这将不允许您访问分配给
Dog
Cat
的任何函数中的
genetic
,除非您还在其构造函数中保留对值的引用。

您是对的,但我希望变量是私有的,因此在创建后不能修改它!用你写的代码,我可以做:d.genetic.code='whadup bro';好的,谢谢,所以我想做的是不可能的。。。你能解释一下你给我的
inherit
函数的区别吗?@Alex:你的函数将
Animal
实例作为原型分配给
Cat
Dog
。这是可行的,但仅当
Animal
不需要任何参数时。我的函数分配
动物的原型(通过临时构造函数“解耦”原型)。您必须在子构造函数中调用父构造函数,但关系更清晰。这是各种库使用的常见模式。你说得对,但我希望变量是私有的,因此创建后不能修改它!用你写的代码,我可以做:d.genetic.code='whadup bro';好的,谢谢,所以我想做的是不可能的。。。你能解释一下你给我的
inherit
函数的区别吗?@Alex:你的函数将
Animal
实例作为原型分配给
Cat
Dog
。这是可行的,但仅当
Animal
不需要任何参数时。我的函数分配
动物的原型(通过临时构造函数“解耦”原型)。您必须在子构造函数中调用父构造函数,但关系更清晰。这是各种库使用的常见模式。