Javascript私有实例变量?

Javascript私有实例变量?,javascript,Javascript,提到Javascript:The Good parts,我试图构建一种类原型对象,然后我可以使用它创建实例。但是,使用通过闭包创建对象和信息隐藏所建议的模式,我发现我创建了一个私有静态成员,而不是私有实例成员 在本例中,我尝试创建一个“account”对象,该对象具有一个私有值(balance)变量,该变量由balance()方法返回: if(type of Object.create!=“函数”){ Object.create=函数(o){ var F=函数(){ }; F.原型=o; 返回

提到Javascript:The Good parts,我试图构建一种类原型对象,然后我可以使用它创建实例。但是,使用通过闭包创建对象和信息隐藏所建议的模式,我发现我创建了一个私有静态成员,而不是私有实例成员

在本例中,我尝试创建一个“account”对象,该对象具有一个私有值(balance)变量,该变量由balance()方法返回:


if(type of Object.create!=“函数”){
Object.create=函数(o){
var F=函数(){
};
F.原型=o;
返回新的F;
};
};
var帐户=函数(){
var值=0;
返回{
“账户名称”:“,
存款:功能(金额){
价值=价值+金额;
},
取款:功能(金额){
价值=价值-金额;
},
平衡:功能(){
返回值;
}
}
}();
var account1=对象。创建(帐户);
var account2=对象。创建(帐户);
account1.account_name=“Mario Incadenza”;
账户1.存款(100);
账户1.提款(25);
account2.account_name=“Hal incadenza”;
账户2.存款(5100);
账户2.提款(2000年);
document.writeln(“账户名称=“+account1.Account\u name+”余额:“%+account1.Balance()+”

”); document.writeln(“账户名称=“+account2.Account\u name+”余额:“+account2.Balance()+”

”);
结果如下:

账户名称=马里奥·因坎丹扎余额:3175

账户名称=Hal INCADENZA余额:3175

看到两个账户的所有取款和存款的总和,很明显我已经创建了一个静态“class”变量(在javaspeak中)

那么,如何在实例级别创建var值并将其隐藏/私有呢?

var account=
声明末尾的
()
表示您只调用了一次初始化函数,并将其返回值赋给一个名为
account
的对象。然后,您将使用该单个对象作为原型创建多个对象,这意味着它们都使用同一个闭包及其单个平衡值

您要做的是将
account
设置为函数,并为每个新对象分别调用它。只需移动括号即可:

var account = function() {
    var value = 0;
    return {
        account_name: "",
        deposit: function (amount) {
            value = value + amount;
        },
        withdrawal: function (amount) {
            value = value - amount;
        },
        balance: function( ) {
            return value;
        }
    }
};

var account1 = Object.create(account());
var account2 = Object.create(account());
但是,一旦您将
帐户
设置为函数,就没有理由使用
对象;您可以直接使用函数的返回值:

var account1 = account();
var account2 = account();
或者,您可以使用
new
(尽管Crockford说
new
是邪恶的)以稍微传统一点的方式做事:


这仍然不是传统的经典Javascript,它只能在
Account.prototype
上定义一次方法。为了完成闭包封装,这个版本必须在每个实例上创建一个新的方法副本

事实上,最好写下这样的内容:

var account = function(/** name, id **/) {
  this.value = 0;
  //this.name = name;
  //this.id = id;
}

account.prototype.deposit = function(amount) {
  this.value += amount;
}

...

您正在为每个实例返回函数,因此它比原型制作花费更多内存。)

JavaJavaScript以前做过,在我看来不值得,最好只做JavaScript。删除函数末尾的调用
()
,并单独调用它们。这是您想要的吗?请注意,Douglas Crockford还没有能够生成文档或演示,在其中他正确使用构造函数。他声称父构造函数不能重复使用,通过更改函数破坏了封装。prototype还希望私有成员阻止其他用户对他的代码执行同样的操作。在他的“helper”函数中,他创建了一个Parent的实例用作Child.prototype你最好在这里学习JavaScript:在这里可以找到一些关于prototype的信息:使用
Object.create()
有什么意义呢
函数每次都会返回一个新对象?非常合理。谢谢我真的不喜欢这个东西。首先要创造东西。我不太清楚克罗克福德先生对“新”的过敏是怎么回事。我理解他的过敏。一般来说,如果您采用类似Java的Javascript并从构建类层次结构开始,那么您可能做错了;不是那种语言。它有
new
这一事实给人一种错觉,认为它就是那种语言,可能会把你引向错误的道路。并非所有内容都必须是具有自己构造函数的自定义类的实例。但是,将信息隐藏在一个单独的东西中并为您操纵它正是对象的用途。另外,由于它会在每个对象上创建新的方法副本,这并不是传统的
new
。我想我仍然不清楚javascript构建“account”这样的对象的方法是什么,很明显,在“存款”和“取款”方法之外,您不会看到对象的内部状态被操纵。如果new是邪恶的,闭包没有给我任何实例级的私有变量,那么什么方法更符合语言的精神呢?或者你是说Crockford反对“new”只是当你试图构建java风格的类层次结构时才使用它,所以在这种情况下使用“new”并不是真的邪恶?是的,你的最后一句话就是我要说的。我不认为我的回答是邪恶的。虽然第一个版本的Object.create有点傻。:)但目标是使该值无法访问。可以从任何地方修改常规对象属性;闭于变数
var Account = function() {
  var value = 0;
  this.deposit = function (amount) {
    value = value + amount;
  };
  this.withdrawal = function (amount) {
    value = value - amount;
  };
  this.balance = function( ) {
    return value;
  }
}

var account1 = new Account();
var account2 = new Account();
var account = function(/** name, id **/) {
  this.value = 0;
  //this.name = name;
  //this.id = id;
}

account.prototype.deposit = function(amount) {
  this.value += amount;
}

...