Stackコンテナ

JavaScriptでStackコンテナと動作確認用コードを書いてみた。

stack.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<meta charset="UTF-8">
		<title>stack操作</title>
		<script language="javascript" src="./stack.js"></script>
		<script language="javascript" src="./html.js"></script>
	</head>
	<body>
		<select id="idSlct">
			<option>stack0</option>
			<option>stack1</option>
			<option>stack2</option>
		</select>
		
		<p>
			<input type="text" id="txtPush"><button id="btnPush">Push</button><br>
			<input type="text" id="txtPop" readonly><button id="btnPop">Pop</button>
		</p>
		
		<p id="idPara">
			dump
		</p>
	</body>
</html>

stack.js

'use strict';

// Stack宣言
var Stack;

// Stack衝突確認
if (!Stack) {
	// 衝突なければオブジェクト設定
	Stack = {};
} else {
	// 衝突したら例外発生
	throw new Error('conflict Stack');
}

// 匿名関数即実行
0, function() {
	
	// Nodeコンストラクタ定義
	function Node(obj) {
		this.value = obj;	// 保持するオブジェクト
		this.next = null;	// nextポインタ
	}
	
	// Stackコンストラクタ定義
	function Create() {
		this.dummy = new Node(null);	// ダミーノード
	}
	
	// Pushメソッド定義
	Create.prototype.Push = function(obj) {
		// ノードインスタンス生成
		var node = new Node(obj);
		
		// nodeのnextにダミーノードのnextを設定
		node.next = this.dummy.next;
		
		// ダミーノードの次にnodeを設定
		this.dummy.next = node;
	};
	
	// Popメソッド定義
	Create.prototype.Pop = function() {
		var rtn = this.dummy.next;
		
		if (rtn != null) {
			this.dummy.next = rtn.next;
		}
		
		return rtn;
	};
	
	// Dumpメソッド定義
	Create.prototype.Dump = function() {
		var node;
		var rtn = '';
		
		for (node = this.dummy.next; node != null; node = node.next) {
			rtn += node.value + '\n';
		}
		
		return rtn;
	};
	
	// Stack.Createにコンストラクタ設定
	Stack.Create = Create;

}();	// 匿名関数即実行

html.js

'use strict';

window.addEventListener('load', function() {
	// エレメント取得設定
	var elem = {};
	elem.slct = document.getElementById('idSlct');
	elem.btnPush = document.getElementById('btnPush');
	elem.btnPop = document.getElementById('btnPop');
	elem.txtPush = document.getElementById('txtPush');
	elem.txtPop = document.getElementById('txtPop');
	elem.para = document.getElementById('idPara');

	// Stack管理オブジェクト
	var stack = {
		length:elem.slct.length,		// stackインスタンス数
		aryStack: [],					// stackインスタンス配列
		actStack: null					// activeなStack
	};
	// Stack生成 slctのoptionの数だけ生成
	
	for (var i = 0; i < stack.length; i++) {
		stack.aryStack[i] = new Stack.Create();
	}
	// slctで選択されたスタックをアクティブに設定
	stack.actStack = stack.aryStack[elem.slct.selectedIndex];
	elem.para.innerHTML = '<pre> \n' + stack.actStack.Dump() + '\n</pre>\n';
	
	// selectBox変更イベント
	elem.slct.addEventListener('change' , function() {
		// アクティブスタックを変更
		stack.actStack = stack.aryStack[elem.slct.selectedIndex];
		
		// paragraphにアクティブスタックをダンプ
		elem.para.innerHTML = '<pre> \n' + stack.actStack.Dump() + '\n</pre>\n';
	}, false);

	// Pushボタンクリックイベント
	function btnPushClick(e) {
		// txtPushから文字列を取得してアクティブスタックにPush
		stack.actStack.Push(txtPush.value);
		
		// txtPushにフォーカス
		elem.txtPush.focus();
		// 選択状態にする
		elem.txtPush.select();
		
		// paragraphにアクティブスタックをダンプ
		elem.para.innerHTML = '<pre> \n' + stack.actStack.Dump() + '\n</pre>\n';
	}
	elem.btnPush.addEventListener('click' , btnPushClick, false);
	
	// Pushテキストキー押下イベント
	elem.txtPush.addEventListener('keypress', function(e) {
		// Enter
		if (e.keyCode == 0x0D) {
			btnPushClick(e);
		}
		
	}, false);

	// Popボタンクリックイベント
	elem.btnPop.addEventListener('click' , function() {
		// アクティブスタックからPop
		var node =stack. actStack.Pop();
		
		// txtPopに設定
		if (node != null) {
			elem.txtPop.value = node.value;
		} else {
			elem.txtPop.value = '<nothing>';
		}
		
		// paragraphにアクティブスタックをダンプ
		elem.para.innerHTML = '<pre> \n' + stack.actStack.Dump() + '\n</pre>\n';
	}, false);

}, false);