2015-10-29 91 views
1

参考Javascript:好的部分,试图建立一种类原型对象,然后我可以用它来创建实例。但使用建议通过闭包创建对象和信息隐藏的模式,我发现我创建了一个私有静态成员而不是私有实例成员。Javascript私人实例变量?

在这种情况下,我试图创建一个“帐户”对象,其具有由所述平衡()方法返回一个专用值(平衡量)变量:

<head> 
    <script> 
     if (typeof Object.create !== 'function') { 
      Object.create = function (o) { 
       var F = function() { 
       }; 
       F.prototype = o; 
       return new F; 
      }; 
     }; 
     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; 
       } 
      } 
     }(); 
    </script> 
</head> 
<body> 
    <script> 
     var account1 = Object.create(account); 
     var account2 = Object.create(account); 
     account1.account_name = "Mario Incandenza"; 
     account1.deposit(100); 
     account1.withdrawal(25); 
     account2.account_name = "Hal Incandenza"; 
     account2.deposit(5100); 
     account2.withdrawal(2000); 
     document.writeln("<p>Account name = " + account1.account_name + " Balance: " + account1.balance() + "</p>"); 
     document.writeln("<p>Account name = " + account2.account_name + " Balance: " + account2.balance() + "</p>"); 
    </script> 
</body> 

下面是结果:

帐户名=马里奥Incandenza余额:3175

帐户名=哈尔Incandenza余额:3175

所以看到所有的取款和存款这两个帐户的明显的和我已经创建了一个静态的“阶级”(在javaspeak)

可变因此,如何在实例级别创建VAR值,并保持它隐藏/私有?

+0

JavaJavaScript之前已经做过的HTTPS ://www.gnu.org/software/easejs/,不值得它海事组织,更好的做JavaScript。 – elclanrs

+2

删除函数末尾的调用'()',并分别调用它们 – webdeb

+0

http://jsfiddle.net/jul101/tcyztz68/这是你想要的吗? –

回答

3

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()); 

但是,一旦你做出account功能,没有理由使用Object.create;你可以直接使用该函数的返回值:

var account1 = account(); 
var account2 = account(); 

或者,你可以做的事情在一个稍微更传统的方式与new(即使克罗克福德说:new是邪恶):

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(); 

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

+5

什么是使用'Object.create()'然后,当你的'account()'函数已经返回一个新的对象时间? – nnnnnn

+0

没有一个。 –

+0

非常明智。谢谢。我真的不喜欢Object.create的东西开始。我不完全确定我明白克罗克福德先生对“新”的过敏是什么。 – user1023110

-2

其实倒不如写类似:

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

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

... 

你正在返回的功能为每个实例,所以它的成本更多的内存,然后原型..;)

+0

但目标是使价值无法访问。常规的对象属性可以在任何地方修改;封闭变量仅存在于返回对象中的函数体内。 –

+0

是的..这是真的..我是专注于内存泄漏.. – webdeb

+0

@webdeb什么内存泄漏?原代码中没有内存泄漏。 “更多的内存消耗”!==========内存泄漏 – zerkms