【问题标题】:Javascript prototype and issues accessing classJavascript原型和访问类的问题
【发布时间】:2011-08-25 09:20:41
【问题描述】:
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 是一个嵌套类。它的父类是 Family。

我收到Family.People 未定义的错误。有人可以更正上面的代码吗?

【问题讨论】:

  • 你可能想把 var 放在 Family 和 People 前面,但是,为什么不为 People 创建一个原型,为什么要为 Family.People 做呢?
  • @James Black,在第二种情况下会出现语法错误......你不能在对象文字中包含 var
  • 缺少的逗号在第 3 行的末尾。另外,你肯定不想打电话给Family = new function(...) {...}new 用于对象构造;在这种情况下,您只需要Family = function(...) {...}

标签: javascript oop class object prototype-programming


【解决方案1】:

工作代码

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

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

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

这会奏效。但你必须注意,当你打电话时:

var f = new Family("Doe");

f.People 只是一个对象构造函数,而不是某个其他对象的实例。您还必须实例化它:

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

你的实例中有一个相当混乱的构造函数。

更好的方法

因此,如果您以这种方式编写原型可能会更好:

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; };
};

这实际上在类中创建了一个类(而不是在实例中)。所以上面的行会这样调用:

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

f 实例的向下钻取如下所示:

f
  _Name
  getName()
  members
    _Number
    clearNumber()

私有变量

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; };
};

通过这种方式,我们将变量设为私有且只能在内部访问,因此无法在外部对其进行操作。您必须始终使用函数来操作它们。这使它更加健壮,尤其是在存在与变量值相关的某些业务规则时。

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

f 实例的向下钻取现在看起来更像是一个类对象实例:

f
  getName()
  members
    getNumber()
    clearNumber()

【讨论】:

  • @Robert Awesome ;] 感谢您提供出色的代码示例。 +1 提高可读性
  • 通过@Robert 的重构,如果需要,您还可以选择关闭namenum,以保留封装。只需直接引用它们并删除分配行。
  • @Paul:没错!我更新了我的答案以包含该信息。封装使它们现在看起来像实际的类......
  • @Robert:很酷,感谢您的提示。从技术上讲,您甚至不需要在本地范围内重新声明/分配参数,尽管这可能是一种风格。我想它清楚地表明我们想要保留这个论点。
  • @Deeptechtons:查看我编辑的答案,其中解释了如何进一步改进。
【解决方案2】:

请注意,您正在分配给Family.prototype.People,然后尝试访问Family.People

Family 不是Family实例,因此它不具有该类的属性-FamilyFunction 的实例,因此您正在尝试访问@987654327 @ 在第三个声明中。 (这有点简化)

即你想做的是

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

你在人之前也少了一个逗号,但我认为这是一个错字......

【讨论】:

  • 您能否更正该代码。我理解了大部分解释,但无法得出解决方案。我要做的就是var x = new Family('myName').Family.People.ClearNumber();我该如何正确地做到这一点。
  • 查看我的编辑(为什么你有第二个家庭?你没有设置Family.prototype.Family,所以这将是未定义的......你想调用的是var x = new Family('myName').People.ClearNumber();
【解决方案3】:

您应该将 People 构造函数声明为 Family 对象中的键:

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

Family 原型将位于 Family 类型的新对象的原型链中;不是家庭本身的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多