08 | 2017/09 |  10

  1. 無料サーバー

User forum-FC2BLOG-Info-Edit Template-Post-Edit-Upload-LogOut

CSSやJavascript自習の苦闘史を綴っていきたい。恐縮ですがJavascriptを有効にしてご覧ください。
2005年12月から社会問題も掲載!

スポンサーサイト

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

 

クロージャーに関するメモ

ユニークカウンター・クロージャー

よく見かけるクロージャーの例として次のカウンターがあります。

■ カウンタークロージャー
var counter = (function(){
    var id = 0;
    return function(){ return id++}
})();

// この counter 関数を次のように実行すると、その都度異なる値が返されるので、
// ユニークカウンターとして使うことが出来ます。
/* 1 度目 */  counter(); // 返値は 0
/* 2 度目 */  counter(); // 返値は 1
・・・・

このカウンタークロージャーは、外からカウンター値を弄れないため、まさにユニークな「変えられない」カウンターとして使えることから、一部では推奨されています。(『Javascript 第 5 版』等)

確かに、この counter 関数を任意のコードに組み込んでその中でカウンターとして使えば、任意のコードが呼び出された回数を確実に測定することが出来ます。(但し、そのコードを再読み込みすればゼロに戻ってしまいますが・・・)

奇数/偶数を記録するクロージャー

上を踏まえて、奇数 / 偶数をトグルで返すクロージャーを作ってみました。

■ 奇数/偶数トグルクロージャー
var state = (function(){
    var odd = 1;
    return function(){ return odd++ % 2 == 1 ? true : false }
})()

この state 関数を次のように実行すると交互に true / false が返されます。
/* 1 度目 */  state(); // 返値は true
/* 2 度目 */  state(); // 返値は false
/* 3 度目 */  state(); // 返値は true
/* 4 度目 */  state(); // 返値は false
・・・・

ここに false を偶数、true を奇数と読み替えれば、state 関数は交互に偶数と奇数を返すものとなります。しかも、その値を外から操作することは出来ません。

これをコード内で利用すれば、例えば起動回数が奇数回か偶数回かを返して、場合分けを行うことが出来ます。

▲ToTop

これらは何故クロージャーなのか?

さて、以上の 2 つのクロージャーから、何故これらが単なる関数ではなく「クロージャー」と言われるのか、その所以を学習しようと思います。

これらの 2 つの関数に共通することは、入れ子になった関数がグローバル変数に返されていることです。そのため、外側の関数の実行が終了しても、入れ子になったそれぞれの関数に対するグローバルスコープからの参照が生き続けます。

こうしてグローバル環境から、いつでも入れ子になった関数にアクセスできることになります。

なお、関数がリテラル表記されていることは本質には何ら関係ありません。次のように書いてもクロージャーであることに何ら替わりはなく、同一の挙動をするからです。リテラル表記の方が簡潔に同一のことを表現できるに過ぎません。

function state (){
    var odd = 1;
    return function(){ return odd++ % 2 == 1 ? true : false }
}
var log = state();
/* 1 度目 */  log() // result:true
/* 2 度目 */  log() // result:false
/* 3 度目 */  log() // result:true
/* 4 度目 */  log() // result:false
・・・・
クロージャーはどこにある?

ここで、まずはっきりさせなければならないことは、「 クロージャー 」と言われる部分はどこなのか、ということです。恥ずかしながら、counter 関数や state 関数がクロージャーなのか、それとも入れ子になった関数がそれなのか、しばらく理解しないまま時が経過してしまったので、ここで明らかにしたいのです。

実は、改めて Javascript 第 5 版を読み直し、また非常に分かりやすいサイト クロージャと高階関数 をじっくり読んで、やっと理解出来たのは、つい最近のことなのです。

「 クロージャーとは、その関数が定義された環境への参照を持った関数のこと 」───上記サイト『クロージャと高階関数』のこの定義が曇った頭をすっきりさせてくれました。またよくよく読み返してみると、Javascript 第 5 版 において 「 クロージャーとしての入れ子型の関数 」(p.142)と表現されているではありませんか!

つまりクロージャーは外側の関数ではなく、その中にある入れ子になった関数です。「入れ子になった関数を定義した環境」とは、外側の関数の変数とその有効範囲(スコープ)を意味するわけで、上の 2 つの例では共に、入れ子になった関数が定義された環境とは、グローバル環境下にある関数の中に存在するローカル環境です。

クロージャーは、どんな場合に 「 生き続けるか? 」 (つまり、グローバル環境から参照できるか?)

さて、入れ子になった関数はよく使われますし、その関数が外側の関数環境への参照をもっていることも決して少なくありません。例えば、次のように外側の関数の引数や内部の変数を、内側の関数から参照するようなコードを書けば、内側の関数は 「 定義された環境への参照を持った関数 」 になります。つまり内側の関数はクロージャーです。

// 関数 sample はグローバル環境にある。
function sample(x){ // グローバル関数 sample 直下に、環境 Lc1 が格納されている。
  var y = 1; // 環境 Lc1 には x、y、z の 3 つの変数がある。
  // 環境 Lc2 から環境 Lc1 の中にある x と y を参照している。
  var z = function(){ return y + x++; /*環境 Lc2*/};
  return z();
};
/* 1 度目 */  sample(2) // result:3
/* 2 度目 */  sample(2) // result:3
/* 3 度目 */  sample(2) // result:3
・・・・

しかし、いくらクロージャーがあっても、それだけではグローバル環境から内側の関数は参照出来ません。

上の例では、確かに内側の関数から外側の関数への参照( 参照 Lc2 → Lc1 )は存在しますが、グローバル環境から内側の関数への参照( 参照 G → Lc2 )が存在しません。 Lc1 への参照を持ったクロージャー(それは Lc2 環境にある)に対して、グローバル環境 G からアクセス出来なれば、外側の関数が終了すればそれと共にクロージャーもガーベージコレクションされてしまいます。

この点こそがポイントです。グローバル環境からクロージャーを参照する何らかの措置(例えば Lc2 環境からの return 値をグローバル環境に返す)を施して、グローバル環境から内側の関数にアクセス出来るようにすれば、外側の関数実行が終わった後においても、グローバル環境からクロージャーへの参照を利用して、結果として Lc1 環境へのアクセスが可能となります

模式的に書けば、G → Lc2 → Lc1 ( → は左側の環境から右側の環境への参照を表す) となるとき、Lc2 環境の関数がクロージャーになります。

多くのクロージャーサンプルは、内側の関数からの return 連鎖を利用してグローバル変数と内側の関数をリンクさせていますが、グローバル環境からの内部関数への参照を設定することが、クロージャーを効果的に利用する「 秘策 」となります。

 

■ コメントの投稿 ■

管理者にだけ表示を許可する

●トラックバック●

■トラックバックURLはこちら■
http://hkom.blog1.fc2.com/tb.php/732-99b97893

●参照元一覧●

<provided Fc2>
<provided i2i>

▲ToTop

 90%近いシェアを握っているインターネットエクスプローラの描画エンジンを利用したタブbrowser。沢山のタブbrowserがあるが、多機能、カスタマイズフリー、スクリプト利用等で一日の長がある。Gekkoエンジンへの対応も行われ、IEからの自立独立の方向に向かっている。2005年7月にはIE7が登場する見通しの中で、今後の発展が望まれる。

 多様なCSS作成支援機能を備えた、タグ入力式 HTML&CSS作成支援エディタ。スキンデザインもすっきりしている。テキストエディター上で作成するよりも確実で安全にタグ打ちが出来る。
文字コードを選べないのが欠点。

 StyleNote同様のタグ入力式 HTML&CSS 作成支援エディタ。長年使用してきたが現在StyleNoteに乗り換えつつある。

 クリップボード履歴情報を活用する為のソフト。画像まで履歴を取ってくれるのが嬉しい。このソフトを使わない日は絶対ない程に重宝し、愛用している。

 起動中のウィンドウの「コピーできない」説明文などの文字列を取得し、コピー可能な文字データにするツール。何かと便利。

 ストリーミングデータを保存することが出来るソフト。動画利用には不可欠なソフトだ。

 無料ながらレイヤー機能を有し、スクリプトによる拡張も可能な、sleipnir作者が提供している優れもの画像編集ソフト。

 画面キャプチャソフトと言えばこれに勝るものなし、ではないだろうか? 様々な取得方法を有しており、ブログ作成にもHomepage作成に不可欠だ。Jtrimと並んでWoodyBellsの作品。

 複数ファイルの同時編集は出来ないが、透過pngも作れる画像編集ソフト。
(以下当該サイトから抜粋)初心者にも簡単に操作が出来るフォトレタッチソフトです。多くの加工機能で画像に様々な効果を与えることができます。非常に軽快に動作するため、ストレスなく操作できます。

 Animation Gifファイルを作れる無料ソフト。

 キャプチャソフト。画面内にサイト全体が表示しきれない場合でも、これを使えば全体をキャプチャすることが出来る。

 画像処理。画像のフォーマット変換のみならず、色数やサイズ、圧縮率の変更まで一括処理できてしまう『BatchGOO!』は、大量の画像をまとめて処理したいときに大変便利なソフト。BMP, TIFF, JPEG, PCX, PNG の相互変換をはじめ、色数・サイズ・解像度の統一、JPEG圧縮率の調節など、ホームページ用の画像や携帯電話用の壁紙を揃えるのに抜群の相性を見せる。(Vectorの当該ソフト紹介頁より抜粋引用)

 名前から直ぐに想像が付くように画像のサイズを測るためのソフトだ。Homepage作成には欠かせない。2カラム、3カラムのレイアウトを行う場合に大変重宝する。

 ランチャーソフトは沢山あるが、中でもこれが一押しだ。2年以上使ってきたがその操作性には毎日満足している。これを使い始めてからデスクトップには一切のアイコンを表示することをやめてしまった。

 AdobeReader7によって、起動時間が長すぎるという長年のユーザーの不満はある程度解消した。そのためこの高速化ソフトは存在価値が低下してしまったかもしれない。AdobeReader6迄はこのソフトによる起動高速化で恩恵を受けてきた。

 IE専用が難点だが、様々なサイト内でIDやパスワードを入力するのに重宝するソフト。コンテキストメニューから簡単に起動できるのがGood! sleipnir等のIEの描画エンジンを利用しているブラウザでも使える。

 利用しているパソコンの諸元値を取得するには、このソフトがベストだ。インストール済みソフトの一覧が取得できるのも嬉しい。

 WMPは機能が豊富なだけ重い。RealPlayerも同様だ。そこでMedia Player Classicを使いたい。動作が軽快なだけではなく、対応しているファイル形式もすこぶる多く、これひとつで、wmvもrmも表示できてしまうのだから凄い! 数多あるMedia Playerの王様と言えるだろう。

 自宅でPCを起動しているときには必ず起動しているメディアプレーヤー。何かと過剰なWinampよりも、起動も速くスキンはシンプルだ。

 DivX, Xvid, Mov, Vob, Mpeg, Mpeg4, avi, wmv, dv, などの動画をDVD-Video形式に変換できるフリーソフト。クリックするとDVD関連ソフト紹介サイト=「DVDなToolたち」なるHomepageが開きます。

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