主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

JavaScript: オブジェクト指向プログラミングってなんぞ

                
tags: JavaScript
 プログラミングを学ぼうとして、C言語でポインタやファイル入出力など基礎的なことができている状態でJavaScriptに触り始めた。C言語とJavaScriptの大きな違いはなにかというとオブジェクト指向の言語かどうかということだ。
 ぼくがJavaScriptを学び始めたのはちょいと作りたいものがあったからで、オライリーの初級者向けの本を見ながらそれを作ってしまった。基礎的なオブジェクトと関数だけ使って、オブジェクト指向はよくわからなかったから無視して。おかげであとから読み返しづらいスクリプトができあがってしまった。作ったのは下記のリンクにあるもので、三か国のAmazonでのお買いものをシミュレーションして、商品金額から送料まで含めて比較ができる。
http://amazonstinger.appspot.com/

↓が上記のWebアプリ?のスクリプト。冒頭でグローバルのアレイを宣言してその下にいくつも続く関数でそのアレイをいじりまわしている。どの関数がなにをしているか読みづらい、わけわからん。
ama_old.js

このたびはオブジェクト指向というのがなにかわかってきたので、上のスクリプトをオブジェクト指向で書き換えてみた。買い物金額算定のための関数を一つのオブジェクト下にまとめた。
ama_new.js


 オブジェクト指向プログラミングとはオブジェクトを適切に使ってプログラミングをしろってことで、じゃあオブジェクトってなにか。
 まずオブジェクトなしで、適当な処理にかかる経過時間を計るスクリプトを書いてみる。
http://jsfiddle.net/hiroaki/A4ee7/
function func1 ()
{
for (var i=0; i<10000; i++)
{
var newEle = document.createElement("div");
var str = document.createTextNode("foo");
newEle.appendChild(str);
document.getElementById("content").appendChild(newEle);
}
}

function main ()
{
// 処理の開始時刻を得る
var time = Date.now();

func1();

// 現在時刻から開始時刻を引くことで、経過時間を得る
// ミリ秒単位から秒単位に変換してコンソールに表示
console.log((Date.now() - time) / 1000);
}
main();

 関数func1は気にする内容がないので、関数mainの中を見る。時間を入れておく変数timeと、その変数timeを使って経過時間を算出する処理が書かれている。

 オブジェクトを出すまえにもう1ステップ。関数func2を作って、関数func1と処理時間の差を計測してみる。
http://jsfiddle.net/hiroaki/A4ee7/1/
function func1 ()
{
for (var i=0; i<10000; i++)
{
var newEl = document.createElement("span");
var str = document.createTextNode("func1");
newEl.appendChild(str);
document.getElementById("content").appendChild(newEl);
}
}

function func2 ()
{
var contentEl = document.getElementById("content");
for (var i=0; i<10000; i++)
{
var newEl = document.createElement("span");
var str = document.createTextNode("func2");
newEl.appendChild(str);
contentEl.appendChild(newEl);
}
}

function main ()
{
var time1 = Date.now();
func1();
var elapsed1 = (Date.now() - time1) / 1000;

var time2 = Date.now();
func2();
var elapsed2 = (Date.now() - time2) / 1000;

console.log(elapsed1 - elapsed2);
}

main();

変数や処理の記述が増えてきた。他人がこのスクリプトを読むと、変数time1やtime2に開始時刻を入れて、そのあと変数elapsedに開始時刻と現在時刻の差を取ってと処理の流れを追うことで、「func1とfunc2の処理時間の差を計っているんだ」と理解できる。ここでは簡単な処理しか書いていないからまだスクリプトが読めるが、スクリプトがなにをしているかを知るには処理を目で追って理解する必要がある。

 ここでオブジェクトを使ってみる。
http://jsfiddle.net/hiroaki/A4ee7/2/
// define Stopwatch ******
function Stopwatch()
{
this._startTime = null;
this._elapsed = null;
}

Stopwatch.prototype.start = function()
{
this._elapsed = null;
this._startTime = Date.now();
};

Stopwatch.prototype.stop = function()
{
if (this._startTime)
{
this._elapsed = (Date.now() - this._startTime) / 1000.0;
this._startTime = null;
}
};

Stopwatch.prototype.getElapsed = function()
{
if (this._elapsed)
{
return this._elapsed;
}
else if (this._startTime)
{
return (Date.now() - this._startTime) / 1000.0;
}
else
{
return null;
}
};
// ******

function func1 ()
{
for (var i=0; i<10000; i++)
{
var newEl = document.createElement("span");
var str = document.createTextNode("func1");
newEl.appendChild(str);
document.getElementById("content").appendChild(newEl);
}
}

function func2 ()
{
var contentEl = document.getElementById("content");
for (var i=0; i<10000; i++)
{
var newEl = document.createElement("span");
var str = document.createTextNode("func2");
newEl.appendChild(str);
contentEl.appendChild(newEl);
}
}

function main ()
{
// オブジェクトstopwatch1, stopwatch2を作成
var stopwatch1 = new Stopwatch();
var stopwatch2 = new Stopwatch();

stopwatch1.start();
func1();
stopwatch1.stop();

stopwatch2.start();
func2();
stopwatch2.stop();

console.log(stopwatch1.getElapsed()
- stopwatch2.getElapsed());
}

main();

 オブジェクトの定義方法は、オブジェクトがどんな働きをしてくれるかを知ってから学べばいい。引き続き関数mainの中に着目する。
 開始時刻を入れていた変数timeや経過時間を得るために書いていた処理が消えており、代わりにstopwatch1とstopwatch2という変数がなにかをしている。stopwatch1の処理を追ってみると、作成されたのち、startという関数の実行、stopという関数の実行、getElapsedという関数の実行という順番でなにかをしている。意味を追えば、開始、停止、経過時間の取得という意味だ。ブラウザの開発ツールを開いてコンソールを見てみれば、さっきまでのオブジェクトを使っていないスクリプトと同様に、関数func1とfunc2の処理時間の差が出力されている。
 オブジェクトなしのスクリプトと比べれば、処理時間計測に使われている変数timeや経過時間計算の処理が関数mainのなかからなくなっている。関数mainの中がシンプルになっている。stopwatchというオブジェクトがstartやstopという関数を実行しているので、詳しい処理を追わなくても、即座に「時間を計測しているんだな」と見当を付けることができる。これがオブジェクト。まるで物のような動作を提供してくれる。今回の例ではその物というのがそこらにあるストップウォッチだった。



            

コメントの投稿

非公開コメント

プロフィール

hMatoba

Author:hMatoba
Github

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。