一些小的修正。在 JS 中,这些只是类模拟——该语言缺乏实际类的形式化概念。而且您的 JSON 表示法实际上是一个 JS 对象 - 这将是您当前拥有的无效 JSON。
您不必使用对象来模拟单例模式。您可以使用如下构造函数执行此操作:
function Animal() {
if (Animal.instance) return Animal.instance;
Animal.instance = this;
/* constructor code here */
}
var animal_a = new Animal(); //constructor runs
var animal_b = new Animal(); //singleton instance returns
console.log(animal_a === animal_b); //true
此外,对于您的第一种方法,请注意最好将可重用、可继承的代码放在原型上,而不是为每个实例单独声明。这更快,也更明智 - 原型就是这样做的地方。
function Animal() {}
Animal.prototype.method = function() {}
这也避免了区分自己的和继承的属性的问题,在您的代码中,由于您在每个实例上分别声明方法,因此无法做到这一点。
[编辑- 回应 OP 关于私人成员的问题]
私有成员被实现为局部变量/函数,这意味着它们在当前闭包之外是不可访问的。
function Animal() {
var private_var = 'foo';
function private_method = function() { alert('bar'); };
}
公共方法可能(如果您选择)能够获取或设置它们 - 但为了它们自己可以访问这些私有成员,它们必须在构造函数内部声明,而不是在构造函数外部单独声明。
function Animal() {
var private_var = 'foo';
function private_method = function() { alert('bar'); };
if (!Animal.prototype.public_method)
Animal.prototype.public_method = function() {
alert(private_var);
};
}
var dog = new Animal();
dog.public_method(); //'foo'