最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

oop - Javascript prototype and issues accessing class - Stack Overflow

programmeradmin4浏览0评论
Family = function(name) {
  this._Name = name;
}

Family.prototype = {
  getName: function() {
    return this._Name;
  },
  People: function(num) {
    this._Number = num;
  }
}

Family.People.prototype = {
  clearNumber: function() {
    this._Number = 0;
  }
}

People is a nested class. Its parent class is Family.

I get the error that Family.People is undefined. Could someone correct the code above?

Family = function(name) {
  this._Name = name;
}

Family.prototype = {
  getName: function() {
    return this._Name;
  },
  People: function(num) {
    this._Number = num;
  }
}

Family.People.prototype = {
  clearNumber: function() {
    this._Number = 0;
  }
}

People is a nested class. Its parent class is Family.

I get the error that Family.People is undefined. Could someone correct the code above?

Share Improve this question edited Dec 28, 2011 at 22:40 Tom van der Woerdt 30k7 gold badges74 silver badges105 bronze badges asked May 14, 2011 at 5:06 DeeptechtonsDeeptechtons 11.1k27 gold badges105 silver badges178 bronze badges 3
  • You may want to put var in front of Family and People, but, why not create a prototype for People, why do it for Family.People? – James Black Commented May 14, 2011 at 5:13
  • @James Black, that would give a syntax error in the second case... you can't have a var inside an object literal – tobyodavies Commented May 14, 2011 at 5:14
  • The missing ma is at the end of line 3. Also, you definitely do not want to call Family = new function(...) {...}. new is used for object construction; in this case you just want Family = function(...) {...} – Tess Rosania Commented May 14, 2011 at 5:14
Add a ment  | 

3 Answers 3

Reset to default 7

Working code

// function doesn't need "new" operator
var Family = function(name) { this._Name = name; };

Family.prototype = {
    getName: function() { return this._Name; }, // missing ma
    People: function(num) {
        this._Number = num;
    }
};

// work with prototypes
Family.prototype.People.prototype = {
    clearNumber: function() { this._Number = 0; }
};

This will work. But you have to be aware, that when you call:

var f = new Family("Doe");

f.People is just an object constructor, and not an instance of some other object. You will have to instantiate it as well like:

f.members = new f.People(3);

Sou you have a constructor within your instance which is rather confusing.

A better approach

So it would probably be better if you'd write your prototypes this way:

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

Family.People = function(num) {
    this._Number = num;
    this.clearNumber = function() { this._Number = 0; };
};

This actually makes a class within a class (and not within instances). So upper lines would be called this way:

var f = new Family("Doe");
f.members = new Family.People(3);

Drill down of f instance would look like:

f
  _Name
  getName()
  members
    _Number
    clearNumber()

Private variables

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

Family.People = function(num) {
    var _num = num;
    this.getNumber = function() { return _num; }
    this.clearNumber = function() { _num = 0; };
};

This way we make variables private and only accessible within so they can't be manipulated outside. You must always use functions to manipulate them. This makes it more robust especially when there are certain business rules related to variable values.

var f = new Family("Doe");
f._name; // this is undefined because "_name" is private closure variable

Drill down of f instance would now look more like a class object instance:

f
  getName()
  members
    getNumber()
    clearNumber()

Notice that you are assigning to Family.prototype.People then trying to access Family.People.

Family is not an instance of Family thus it does not have the properties of that class - Family is an instance of Function thus you are trying to access Function.prototype.People in that 3rd statement. (this is a bit of a simplification)

i.e. what you want to be doing is

Family.prototype.People.prototype = {
  clearNumber:function(){this._Number = 0;}
}

You are also missing a ma before people, but I assume this is a typo...

You should declare the People constructor as a key in the Family object:

Family.People = function(num) {
  this._Number = num;
}

The Family prototype will be in the prototype chain for new objects of type Family; not a part of Family itself.

发布评论

评论列表(0)

  1. 暂无评论