JavaScript タイマー機能の実装

<script>
 //タイマー機能の実装
 //タイマーIDを格納するためのグローバル変数
 var timer;
 //ページロード時にタイマー処理を登録
 window.onload = function(){
     timer = window.setInterval(
         //現在の時刻を<div id='result'>タグに表示(1000ミリ秒ごとに更新)
         function(){
             var dat = new Date();
             document.getElementById('result').innerHTML = dat.toLocaleTimeString();
         },1000
     );
 };
</script>

<!-- ボタンクリック時にタイマー処理を中止 -->
<input type="button" value="タイマー停止" onclick="clearInterval(timer)"/>
<div id="result"></div>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript サブウィンドウを生成する

<script type="text/javascript">
 //サブウインドウを表すWindowオブジェクトを格納する変数
 var subwin;
 //サブウィンドウを開くボタンクリック時に実行
 function win_open(){
     subwin = window.open('http://www.wings.msn.to/', 'Sample',
     'width=600,height=300,scrollbars=yes,location=yes');
 }
 //サブウィンドウを閉じるボタンクリック時に実行
 function win_close(){
     //変数subwinが空でなく、サブウィンドウが閉じられていない時にのみクローズ
     if(subwin && !subwin.closed){
         subwin.close();
     }
 }
</script>

<input type="button" value="サブウィンドウを開く" onclick="win_open()"/>
<input type="button" value="サブウィンドウを閉じる" onclick="win_close()"/>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript ハンドラー3

<script type="text/javascript">
    //ページロード時に実行されるイベントハンドラを登録
    window.onload = function(){
    //ボタンクリック時に実行されるイベントハンドラを登録
    document.getElementById('btn').onclick = function(){
    window.alert('ボタンがクリックされました');
    };
    };
</script>
<input id="btn" type="button" value="ダイアログ表示"/>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript ハンドラー1

<script type="text/JavaScript">

 function btn_onclick(){
     window.alert('ボタンがクリックされました');
 };
 //-->
</script>

<input type="button" value="ダイアログ表示" onclick="btn_onclick()" />

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript 継承

<script>
//クラスベースなオブジェクト指向によく似た継承を実現する方法
 //予め用意したMemberクラスを継承してSpecialMemberクラスを定義する
 function initializeBase(derive, base, baseArgs){
     base.apply(derive, baseArgs);
     for(prop in base.prototype){
         var proto = derive.constructor.prototype;
         if(!proto[prop]){
             proto[prop] = base.prototype[prop];
         }
     }
 }

 //Memberクラスを定義
 var Member = function(firstName, lastName){
     this.firstName = firstName;
     this.lastName = lastName;
 };

 Member.prototype.getName = function(){
     return this.lastName + ' ' + this.firstName;
 };

 //Memberクラスを継承したSpecialMemberクラスを定義
 var SpecialMember = function(firstName, lastName, role){
     initializeBase(this, Member, [firstName, lastName]);
     this.role = role;
 }

 SpecialMember.prototype.isAdministrator = function(){
     return (this.role == 'Administrator');
 };

 var mem = new SpecialMember('Jhon', 'Paul', 'Administrator');
 document.writeln('名前:' + mem.getName());
 document.writeln('管理者:' + mem.isAdministrator());
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript コンストラクタ

<script>
 var Member = function(firstName, lastName){
//thisはコンストラクタによって生成されるインスタンスを表す。
     this.firstName = firstName;
     this.lastName = lastName;
     this.getName = function(){
         return this.lastName + ' ' + this.firstName;
     }
 };

 var mem = new Member(' Jhon', 'Paul');
 document.writeln(mem.getName());
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript クラス

<script>
 //JavaScriptのオブジェクト指向はプロトタイプベースのオブジェクト指向であり
 //クラスベースのオブジェクト指向ではない

 // 「クラス」を定義
 var Member = function(){};

 //インスタンス化
 var mem = new Member();//JavaScriptでは関数にクラスとしての役割を与えている
 //new演算子によってオブジェクトを生成することを想定した関数オブジェクトのことを
 //コンストラクタと言っている。
 //Member関数がコンストラクタにあたる。
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript this

<script>
 var Member = function(firstName, lastName){
//thisはコンストラクタによって生成されるインスタンスを表す。
     this.firstName = firstName;
     this.lastName = lastName;
     this.getName = function(){
         return this.lastName + ' ' + this.firstName;
     }
 };

 var mem = new Member(' Jhon', 'Paul');
 document.writeln(mem.getName());
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

オブジェクト指向 JavaScript1

<script>
 //JavaScriptのオブジェクト指向はプロトタイプベースのオブジェクト指向であり
 //クラスベースのオブジェクト指向ではない

 // 「クラス」を定義
 var Member = function(){};

 //インスタンス化
 var mem = new Member();//JavaScriptでは関数にクラスとしての役割を与えている
 //new演算子によってオブジェクトを制し得することを想定した関数オブジェクトのことを
 //コンストラクタと言っている。
 //Member関数がコンストラクタにあたる。
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript 高階関数

<script>
 //高階関数arrayWalkを定義
 //引数に与えられた配列dataの内容を、指定されたユーザ定義関数fの規則に従って順番に処理するための高階関数
 function arrayWalk(data, f){
     for (var key in data){
         f(key, data[key]);
     }
 }

 //配列を処理するためのユーザ定義関数
 function showElement(key, value){
     document.writeln(key + ':' + value);
 }

 var ary = [1, 2, 4, 8, 16];
 arrayWalk(ary, showElement);
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript arguments

<script>
 function printf(format){
     //引数の2番め以降を順番に処理
     for (var i = 1; i < arguments.length; i++){
         var pattern = new RegExp('\\{' + (i - 1) + '\\}', 'g');
         format = format.replace(pattern,arguments[i]);
     }
     document.writeln(format);
 }
 printf('こんにちは、{0}さん。私は{1}です。', 'tanaka', 'yamada');
</script>
 
<script>
 //printf()は第一引数で指定された書式文字列に含まれるプレイスホルダ(パラメータの置き場所:{1},{2},...)を第二引数以降の値で置き換えたものを出力する関数
 printf('hello,{0} Im{1}','Jhon', 'Mary');
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript 型

<script>
 var num = 1;
 document.writeln(typeof num);
 var str = 'こんにちは';
 document.writeln(typeof str);
 var flag = true;
 document.writeln(typeof flag);
 var ary = ['JavaScript', 'Ajax', 'ASP.NET'];
 document.writeln(typeof ary);
 var obj = {x:1, y:2};
 document.writeln(typeof obj);
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScriptでのHelloWorld

<html>
    <head>
        <meta http-equiv="Content-Type" content=""text/html; charset="UTF-8"/>
        <title>Hello,World!</title>
    </head>
    <body>
        <pre>
            <script type="text/javascript">
                <!--
                     //document.writelnは、指定された文字列を表示するための命令
                     document.writeln('Hello,World!');
                   //-->
            </script>
            <noscript>JavaScriptが利用できません。</noscript>
        </pre>
    </body>
</html>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

標準ライブラリのqsort

#include<stdio.h>
#include<stdlib.h>
int intcomp(int *x, int *y)
{ return *x - *y; }
int a[10000000];
int main(void)
{ int i, n=0;
        while (scanf("%d", &a[n]) != EOF)
                n++;
        qsort(a, n, sizeof(int), intcomp);
        for (i = 0; i < n; i++)
                printf("%d\n", a[i]);
        return 0;
}

Lisp覚書

関数

Lispで関数を呼び出すには関数名をカッコで囲む。関数にパラメータを渡したければそれも一緒にカッコに入れる。

(defun function_name (arguments)
 ...)

まず関数の名前と引数を記し、その後ろに関数を実装するコードを書いていく。

トップレベル定義

Lispではグローバルに定義される変数をトップレベル定義と呼ぶ。新しいトップレベル定義はdefparameter 関数で作ることができる。

(defparameter *small* 1)

アスタリスクはearmuffsと呼ばれる習慣。ローカル変数と区別するのに便利。

REPL(read-eval-printループ)の機能

式をタイプするとLispはそれを直ちに評価して結果を返す。CLISPを終了するときは(quit)とタイプする。
Lispでプログラムを書いているときには、わざわざスクリーンに値を表示させるような関数を書くことは少ない。関数内で表示せずとも返した値は自動的にREPLの機能によって表示される。
他の言語でreturnと書くようなところをLispでは関数の最後の式が自動的に返されるのでその必要がない。

数当てゲーム(バイナリサーチ)

(defparameter *big* 100)
(defparameter *small* 1)

(defparameter *big* 100)
(defparameter *small* 1)

(defun guess-my-number()
  (ash (+ *small* *big*) -1));;(+ *small* *big*)は2つの変数の値を足すコード。加算結果はash関数に渡される。ashは渡された数値を2進数で考え、ビットをシフトする。第二引数に1を渡すと左シフト、-1を渡すと右シフトする。

;;関数の呼び出し
(guess-my-number);;50

(defun smaller()
  (setf *big* (1- (guess-my-number)));;setfでグローバル変数*big*の値を変える。guess-mynumberを呼び*small*と*big*を足して右シフトした値を得て、それを引数として1を引いた関数1-(1-は関数名で、「1を引け」と動詞のように読むと良い)を呼び出す。
  (guess-my-number));;smaller関数によって新しい推測値を表示させるために再びguess-my-numberを呼ぶ。

(defun bigger()
  (setf *small* (1+ (guess-my-number)))
  (guess-my-number))


;;実行
(bigger)
;;75
(smaller)
;;62
(smaller)
;;56

;;グローバル変数をリセットするstart-over
(defun start-over()
  (defparameter *small* 1)
  (defparameter *big* 100)
  (guess-my-number))

(start-over);;50

ローカル変数の定義

ローカル変数の定義にはletコマンドを使う。

(let (変数定義)
     ...本体...)

ローカル関数の定義

ローカル関数の定義にはfletコマンドを使う。最初の2行で関数を宣言する。この関数はfletの本体の中で使える。

(flet ((関数名 (引数)
      ...関数本体...))
  ...本体...
  ||<)

一つの引数nを取るローカル変数fを定義し、本体の中で5を引数として関数fを呼び出す。
>|lisp|
(flet ((f (n)
      (+ n 10)))
     (f 5));;15

コードモードとデータモード

Lispではデフォルトではコードモードになっている。
コードモードにいるとき、その入力はフォームの構造に沿っていなければならない。
フォームとは最初の要素が特別のコマンドになっているようなリストのこと。
フォームを読む際に、リストの残りの要素はすべて引数として関数に渡される。

データモードで書かれてものはすべてデータとして扱われる。
データは「実行」されない。
データモードで固定した情報をデータとしてコード中に埋め込んでおくことができる。
Lispにデータモードであることを教えるにはシングルクオートをリストの手前につける。
これを「クオートする」という。
クオートによって「次に来るのはコマンドじゃないよ、プログラムで使うデータの塊だよ」とLispに教える。

コンスセル

Lispのリストはコンスセルでつなぎ合わされている。
コンスセルはリンクリストである。

cons関数

2つのデータをLispプログラムの中で結び付けたいときに使う。
cons(constructの略)を呼ぶとLispコンパイラはそれぞれのオブジェクトへの参照を入れておく、コンスセルのための小さなメモリをアロケートする。
例えばシンボルchickenをシンボルcatとくっつけると、consはひとつのコンスセルを返す。

(cons 'chicken 'cat);;(CHICKEN . CAT)

コンスセルの表現は繋げられた要素の間にドットをおいて全体をカッコで囲んだもの、リストとは異なる。
Lispではコンスセルの連なりとリストは全く同じもの。

(cons 'pork (cons 'beef (cons 'chicken())));;(PORK BEEF CHICKEN)

空のリスト()はCommon Lispではシンボルnilと同じもので、リストの終端は空のリストである。
3つの要素をコンスすれば、3つの要素を持つリストになる。

car

関数car(Contents of the Address part of the Register)はセルの最初のスロットにあるデータを取り出すのに使う。

(car '(pork beef chicken));;PORK

関数cdr(Contents of the Decrement part of the Register)は2番めのスロットの値を取り出すのに使う。リストの場合はリストの残りの部分を返す(リストの最初の要素を取り除く)。

(cdr '(pork beef chicken));;(BEEF CHICKEN)

list

list関数は長いリストを一気に作ることができる。

(list 'pork 'beef 'chicken);;(PORK BEEF CHICKEN)

空と偽

条件式の評価において空のリストは偽として扱う。

progn

prognコマンドを使って一つの式の中に余分なコマンドを押し込むことができる。最後の式の評価値をフォーム全体の値として返す。progn 特別式は、任意の数の引数を受け付け、先頭の引数から順に全ての式を評価する。

(defvar *number-was-odd* nil)
(if(oddp 5)
         (progn (setf *number-was-odd* t)
                'odd-number)
         'even-number);;==>ODD-NUMBER
*number-was-odd*
==>T

whenとunless

ifの中でひとつ以上の処理を書きたいときにprognを使わなくても、whienやunlessを使えば条件が真の時に囲まれた式をすべて実行する。

(defvar *number-is-odd* nil)
(when (oddp 5)
      (setf *number-is-odd* t)
      'odd-number)
==>ODD-NUMBER

*number-is-odd*
==>T

(unless (oddp 4)
        (setf *number-is-odd* nil)
        'even-number)
==>EVEN-NUMBER

*number-is-odd*
NIL

cond

condは複数の節を引数として受け取る。各節の先頭に条件をチェックする述語があり条件が成立した場合残りの式を評価する。条件が不成立であれば、次の節に移る。条件は常に上から順に検査され、最初に条件を満たしたものがcondの返り値になる。

(defvar *arch-enemy* nil)
(defun pudding-eater (person)
  (cond ((eq person 'henry) (setf *arch-enemy* 'stupid-lisp-alien)
         '(curse you lisp alien - you ate my pudding))
        ((eq person 'johnny)(setf *arc-enemy* 'useless-old-johnny)
         '(i hope you choked on my pudding johnny))
        (t '(why you eat my pudding stranger ?))))
(pudding-eater 'johnny)
==>(I HOPE YOU CHOKED ON MY PUDDING JOHNNY)

*arc-enemy*
==>USELESS-OLD-JOHNNY

(pudding-eater 'george-clooney)
==>(WHY YOU EAT MY PUDDING STRANGER ?)

case

caseでは比較対象になる値を並べて置くだけで良い。

(defun pudding-eater(person)
  (case person
    ((henry) (setf *arch-enemy* 'stupid-lisp-alien)
     '(curse you lisp alien - you ate my pudding))
    ((johnny) (setf *arch-enemy* 'useless-old-johnny)
     '(i hope you choked on my pudding johnny))
    (otherwise '(why you eat my pudding stranger ?))))

andとorを使って条件分岐を行う

andやorは条件判断にも使うことができる。orに与えられた式のうち真になるものが見つかったら直ちに、Lispは残りの式を評価せずにすぐに心を返す。同様に、andに与えられた式のうち偽になるものが見つかったら直ちに残りを評価する手間をかけずに偽値を返す。次のコードはある数が偶数の場合だけグローバル変数を真値にセットする。

(defparameter *is-it-even* nil);;*IS-IT-EVEN*
(or (oddp 4) (setf *is-it-even* t));;T
*is-it-even*;;T

;;奇数を与えると変数の値が変わらないことがわかる。
(defparameter *is-it-even* nil);;*IS-IT-EVEN*
(or (oddp 5) (setf *is-it-even* t));;T
*is-it-even*;;NIL

Land of Lisp

Land of Lisp