日記帳

日記です。

BankAccount

人はなぜ BankAccount を書くのでしょうか?

知らんけど.
ってことで ECMAScript 3rd Edition での BankAccount サンプルです.
ブラウザ向けなので alert() を使ってますがそれ以外の環境なら別の出力関数を使いましょう.rhino*1 や SEE*2 なら print(),WSHJScript なら WScript.Echo() あたりが使えます.

以下書いてみた感想.

  • メソッド呼び出しとプロパティへのアクセスは文法上明確に区別されるのでちゃんと多態しようと思ったらすべてメソッド経由でアクセスする必要がある.自己カプセル化万歳.
  • アクセサメソッドを書いたとしてもプロパティは public なままなので直接変更できてしまう.
  • チャイルドオブジェクトを作るのにコンストラクタとなる関数オブジェクトを作らないといけないのが面倒.(clone() メソッドを作ればいいんでしょうけど http://d.hatena.ne.jp/sa-y/20060304#1141499154 )

ECMAScript 4th Edition ならもっと違うでしょうけど.

BankAccount = new Object()
BankAccount.setDollars = function(dollars){ this.dollars = dollars }
BankAccount.getDollars = function(){ return this.dollars; }
BankAccount.setDollars(200)
alert(BankAccount.getDollars()) // => 200

BankAccount.deposit = function(x){ this.setDollars(this.getDollars() + x) }
BankAccount.deposit(50)
alert(BankAccount.dollars) // => 250

BankAccount.withdraw = function(x){
	this.setDollars((x > this.getDollars()) ? 0 : (this.getDollars() - x));
}
BankAccount.withdraw(100)
alert(BankAccount.getDollars()) // => 150

BankAccount.withdraw(200)
alert(BankAccount.getDollars()) // => 0

BankAccountChild = function(){}
BankAccountChild.prototype = BankAccount

account = new BankAccountChild()
alert(account.getDollars()); // => 0

account.deposit(500)
alert(account.getDollars()); // => 500
alert(BankAccount.getDollars()) // => 0   # prototype の dollars には影響しない

StockAccount = new BankAccountChild()
StockAccount.numShares = 10
StockAccount.pricePerShare = 30
StockAccount.getDollars = function(){
	return this.numShares * this.pricePerShare;
}
StockAccount.setDollars = function(x){
	this.numShares = x / this.pricePerShare;
}
alert(StockAccount.getDollars()) // => 300 # 株数、株単価から計算 
StockAccount.setDollars(150)
alert(StockAccount.getDollars()) // => 150
alert(StockAccount.numShares)    // => 5   # 株数値が変更されている

StockAccountChild = function(){}
StockAccountChild.prototype = StockAccount

myStock = new StockAccountChild()
myStock.setDollars(600)
alert(myStock.getDollars()); // => 600
alert(myStock.numShares); // => 20

myStock.deposit(60)
alert(myStock.getDollars()); // => 660
alert(myStock.numShares); // => 22