javascript:closure
差分
このページの2つのバージョン間の差分を表示します。
javascript:closure [2007/09/25 04:47] – 作成 - 外部編集 127.0.0.1 | javascript:closure [2025/09/10 00:35] (現在) – 削除 nullpon | ||
---|---|---|---|
行 1: | 行 1: | ||
- | ====== クロージャ ====== | ||
- | クロージャとはプログラミング言語において、自身が定義された環境を参照する実行可能なコード片のこと | ||
- | |||
- | ===== クロージャとは ===== | ||
- | outerは高階関数で、関数innerを返します。 | ||
- | |||
- | <code javascript> | ||
- | function outer(fuga) { | ||
- | var hoge = 4; | ||
- | function inner(piyo) { | ||
- | return hoge * fuga * piyo; | ||
- | } | ||
- | return inner; | ||
- | } | ||
- | </ | ||
- | |||
- | 通常、ローカル変数hoge、fugaは関数outerが終了した時点で破棄されますが、outerの戻り値inner関数がローカル変数hoge、fugaを参照し続けるため、破棄されません。 | ||
- | |||
- | <code javascript> | ||
- | var inner = outer(3); | ||
- | print(inner(2)); | ||
- | </ | ||
- | |||
- | このようにローカル変数を取り込んだ関数をクロージャと言います。 | ||
- | |||
- | |||
- | |||
- | ===== コレクションとクロージャ ===== | ||
- | クロージャはコレクションオブジェクトとの相性が非常に良い機能です。Rubyのeachメソッドのようにコレクションオブジェクトの各要素に対して反復処理を行い、処理内容をクロージャで定義すると簡潔に記述できます。 | ||
- | |||
- | <code ruby> | ||
- | # Rubyのイテレータ | ||
- | someArray.each do |enum| | ||
- | p enum | ||
- | end | ||
- | </ | ||
- | |||
- | 関数を関数に引数にできる性質を使って、JavaScriptにRubyの内部イテレータに近い処理を実装することができます。 | ||
- | |||
- | Firefox 1.5では関数オブジェクトを引数として繰り返し処理を行う[[http:// | ||
- | |||
- | ==== eachメソッド ==== | ||
- | |||
- | 配列要素すべてに対して、何らかの処理を加えます。 | ||
- | <code javascript> | ||
- | Array.prototype.each = function(func){ | ||
- | for (var i = 0; i < this.length; | ||
- | func(this[i]); | ||
- | } | ||
- | } | ||
- | |||
- | var someArray = new Array(" | ||
- | |||
- | someArray.each( | ||
- | function(e){print(e); | ||
- | ); | ||
- | </ | ||
- | |||
- | 配列要素すべてが標準出力に書き出されます。 | ||
- | |||
- | ==== selectメソッド ==== | ||
- | Rubyのselectメソッド(コレクションの中から、ある条件に合う要素を探し出し、それら要素を新しい配列として返すメソッド)を独自実装します。 | ||
- | <code javascript> | ||
- | Array.prototype.select = function(func){ | ||
- | var a = new Array(); | ||
- | for(var i = 0; i < this.length; | ||
- | if( func(this[i]) ){ | ||
- | a.push(this[i]); | ||
- | } | ||
- | } | ||
- | return a; | ||
- | } | ||
- | var selectedArray = someArray.select( | ||
- | function(e){return e.length == 4} | ||
- | ); | ||
- | </ | ||
- | 文字列の長さが4である要素のみを取り出した新しい配列が作成されます。 | ||
- | |||
- | |||
- | ==== collectメソッド ==== | ||
- | |||
- | collectメソッド(コレクションのすべての要素にある処理を実行して、その戻り値を要素とする新しい配列を作成するメソッド)を独自実装します。 | ||
- | <code javascript> | ||
- | Array.prototype.collect = function(func){ | ||
- | var a = new Array(); | ||
- | for (var i = 0; i < this.length; | ||
- | a.push( func(this[i]) ); | ||
- | } | ||
- | return a; | ||
- | } | ||
- | var collectedArray = someArray.collect( | ||
- | function(e){return e.charAt(0); | ||
- | ); | ||
- | </ | ||
- | 配列の各要素の最初の一文字を要素とする新しい配列が作成されます。 | ||
- | |||
- | |||
- | ===== hasOwnProperty ===== | ||
- | Arrayのインスタンスに対してfor inループを使うと、Arrayの全要素を列挙できますが、Array.prototypeに対してメソッドが追加されていると、それらの追加メソッドまで列挙されてしまいます。このような場合は、hasOwnPropertyメソッドを使うと、Array.prototypeに追加したメソッドを除外できます。 | ||
- | |||
- | hasOwnPropertyメソッドは指定のプロパティが、オブジェクト自身に属しているならばtrueを返し、prototypeに追加したものはfalseを返します。指定のプロパティが無い場合も当然falseを返します。 | ||
- | <code javascript> | ||
- | for (var item in someArray) { | ||
- | if (someArray.hasOwnProperty(item)) { | ||
- | document.write(someArray[item]); | ||
- | } | ||
- | } | ||
- | </ | ||
- | MacOSX 10.3のsafariにはhasOwnPropertyが実装されていませんが、独自にメソッドを追加して対応することができます。10.4以降のSafariでは必要ありません。 | ||
- | <code javascript> | ||
- | /* for safari */ | ||
- | if (!Object.hasOwnProperty) { | ||
- | Object.prototype.hasOwnProperty = function(it) { | ||
- | return (this[it] && !this.constructor.prototype[it]); | ||
- | } | ||
- | } | ||
- | </ | ||
javascript/closure.1190695649.txt.gz · 最終更新: by 127.0.0.1