01 | 2017/03 |  03

  1. 無料サーバー

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

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

jQueryに学ぶ Javascript の基礎(6) func.apply(obj , array) upon Ver1.3.2──jQuery解読(39)

このエントリイは、 jQueryに学ぶJavascriptの基礎(5) 論理演算子の使い方──jQuery解読(23) の続編です。(5)を書いたのが 2007/12/16 ですから、1 年以上間が空いてしまいました。その点からすれば「続編」と言うよりも「再開編」と言うべきかもしれません。

配列のメソッドである push() に apply() メソッドを適用する

apply() メソッドは Javascript 初心者には取っつきにくい関数です。それが別の関数を対象に適用され、しかも this キーワードが登場し、更に引数を配列で与えなければならない───このように約束事の多い仕様となっているためでしょう。

一般的に遭遇する fn.apply ( this, [ array ] ) という書式は、最初はなかなか理解しがたいものです。これは this.fn ( [array] ) とほぼ同意義なのだと説明されると、その場では分かったような気になりますが、半可通のママでは実際に使いこなすことは出来ません。

私もこの"主客転倒しているかのような" apply() メソッドには、ずっと悩まされ続けてきました。

そもそも apply()は「関数オブジェクトの組み込みメソッドであり、かつ特定の引数を取る」ことを理解すれば、決して複雑怪奇な関数ではないのですが、そのような理解に至るには時間が掛かるのではないでしょうか。(自省の弁)

さて、jQuery ではこのメソッドがあちこちで多用されています。

特に init() メソッドの return 値算出に setArray() メソッドが重要な役割を果たしていますが、この setArray() メソッドの実態は、組み込みクラスのプロトタイプメソッドである push() に適用された apply() メソッドに他なりません。

▲ToTop

対象オブジェクト obj に、配列 「 のような 」 プロパティを付与する

jQuery では push メソッドに apply メソッドを適用することによって、インスタンスオブジェクトに 「 配列のような (array like) 」 プロパティを与えています。そしてその array like なプロパティ値こそ、jQuery ( selector ) によって抽出されたところの、ユーザーが取得しようとしている DOM Elements に他なりません。

以下には今回の学習記録として、具体的な例によって apply() メソッドの効用を明らかにします。

まず、視認性を高めるために、オブジェクトのプロパティを抽出する以下のような汎用ユーティリティを作っておきます。

 // オブジェクトのプロパティ名とプロパティ値を一覧するための関数
 var getProp =function(obj){
    var ret=[];
    for (var prop in obj) ret.push(prop + " : " +obj[prop]);
     return ret.join() ;
 };
一般的な抽象オブジェクトを対象にした例

下の例 1 は、空のオブジェクト obj に push.apply(obj,[array]) を適用した場合です。適用後の obj は 名称が 0 から始まる連番プロパティと length プロパティによって構成され、length 値は第 2 引数の配列数となります。確かに配列のような プロパティが obj オブジェクトに付与されることが分かります。

 /*++++++ apply() 例 1 ++++++*/
 // 空オブジェクトを作成
 var obj={};
 // push 関数に apply(obj,[array])メソッドを適用する
 Array.prototype.push.apply(obj,["test",100,["test",500],400] );
 // 適用結果を一覧する
 getProp(obj) // 結果 "0 : test, 1 : 100, 2 : test,500, 3 : 400, length : 4"

例 2 は、 obj のプロパティ名に、push.apply(obj,[array]) で付与される array like なプロパティ名と重複する名称が既に存在する場合を検証してみました。この場合には obj プロパティが上書きされ、obj.length 値 は objプロパティの総数ではなく、push.apply() の第 2 引数である配列の要素数になることが分かります。

 /*++++++ apply() 例 2 ++++++*/
 // 空ではないオブジェクトを作成
 var obj={0:"test",1:"test1",2:"test2",3:"test3",4:"test4",5:"test5"};
 // このオブジェクトに push.apply(obj,[array]) メソッドを適用する
 Array.prototype.push.apply(obj,[100,200,300] );
 // 適用結果を一覧する
 getProp(obj) // 結果 "0 : 100, 1 : 200, 2 : 300, 3 : test3, 4 : test4, 5 : test5, length : 3"

例 3 は、obj のプロパティ名に 0 から始まる連番名がない場合の検証です。この場合には obj の既存プロパティは変化せず、第 2 引数 [array] の要素が array like なプロパティに姿を変えて追加されます。しかし、obj.length 値は obj プロパティの総数ではなく、あくまでも push.apply() の第 2 引数の配列の要素数となることが分かります。

 /*++++++ apply() 例 3 ++++++*/
 // 空ではないオブジェクトを作成
 var obj={"a":"test","b":"test1","c":"test2","d":"test3","e":"test4","f":"test5"};
 // このオブジェクトに push.apply(obj,[array]) メソッドを適用する
 Array.prototype.push.apply(obj,[100,200,300] );
 // 適用結果を一覧する
 getProp(obj) // 結果 "a : test, b : test1, c : test2, d : test3, e : test4, f : test5, 0 : 100, 1 : 200, 2 : 300, length : 3"

例 4 は、push.apply(obj,[array]) メソッド適用前に、obj.length を指定する意味について考えるために作成したものです。結論を言えば、array like なプロパティ名は obj.lenght で指定した値から始まる連番になります。しかしここでも、obj.length 値は obj プロパティの総数ではなく、あくまでも push.apply() の第 2 引数の配列の要素数となることが分かります。

 /*++++++ apply() 例 4 ++++++*/
 // 空ではないオブジェクトを作成
 var obj={"a":"test","b":"test1","c":"test2","d":"test3","e":"test4","f":"test5"};
 // 適用前にobj.length値を指定
 obj.length = 15;
 // obj オブジェクトに push.apply(obj,[array]) メソッドを適用する
 Array.prototype.push.apply(obj,[100,200,300] );
 // 適用結果を一覧する
 getProp(obj) // 結果 "a : test, b : test1, c : test2, d : test3, e : test4, f : test5, 15 : 100, 16 : 200, 17 : 300, length : 3"

以上から、Array.prototype.push(obj,[array])メソッドについて次のことが分かりました。

  • 同一プロパティ名は上書きされる。
  • obj に付加される array like なプロパティの名称は、前もって obj.length 値を指定した場合にはその値から始まる連番となる。(指定しない場合には obj.length = 0 を指定したことになる。)
  • obj.length 値はどのような場合であっても、obj の総プロパティ数には無関係に、第 2 引数で指定した配列の要素数となる。

▲ToTop

jQuery における push - apply 適用例(行数は Ver 1.3.2 による)

兎にも角にも setArray インスタンスメソッドにその端的な例を見ることが出来ます。

139: // Force the current matched set of elements to become
140: // the specified array of elements (destroying the stack in the process)
141: // You should use pushStack() in order to do this, but maintain the stack
142: setArray: function( elems ) {
143:  // Resetting the length to 0, then using the native Array push
144:  // is a super-fast way to populate an object with array-like properties
145:  this.length = 0;
146:  Array.prototype.push.apply( this, elems );
147:
148:  return this;
149: },

■コメント文を意訳すれば...
(ユーザー指定条件に)マッチした要素群を特別な配列に変換する。(スタックはその
過程で破棄されるので、スタックを活用するためには pushStack() メソッドを使わねば
ならない。 length を 0 に設定すれば、push メソッドを使って、超高速にオブジェクトを
配列のようなプロパティに変換することが出来る。

146 行の apply メソッド適用により、this すなわちインスタンスオブジェクトのプロパティに elems が配列のようなプロパティとして組み込まれることになります。

setArray() テスト

以上をより具体的に理解するために、Local 環境下に、<p> が 10 個存在する Web サイトを作成し、その中で jQuery ("p") .setArray ( ["a","b","c","d","e"] ) メソッドの適用結果を色々な形で求めてみました。

以下の出力結果は Firebug のコンソールに表示された内容です。
入力 : $("p").setArray(["a","b","c","d","e"]).get()
出力 : a,b,c,d,e
入力 : getProp( $("p").setArray( ["a","b","c","d","e"] ).get() )
出力 : "0 : a, 1 : b, 2 : c, 3 : d, 4 : e"
入力 : getProp( $("p").setArray(["a","b","c","d","e"]) )
出力 :
   length : 5,
   prevObject : [object Object],
   context : [object HTMLDocument], 
   selector : p, 
   0 : a, 
   1 : b, 
   2 : c, 
   3 : d, 
   4 : e, 
   5 : [object HTMLParagraphElement], 
   6 : [object HTMLParagraphElement], 
   7 : [object HTMLParagraphElement], 
   8 : [object HTMLParagraphElement], 
   9 : [object HTMLParagraphElement], 
   // 以下はプロトタイプオブジェクトを参照するプロパティ
   init : function (selector, context) { ・・・・(以下略)
参考
入力 : getProp( $("p") )
出力 :
   length :10,
   prevObject : [object Object],
   context : [object HTMLDocument], 
   selector : p, 
   0 : [object HTMLParagraphElement], 
   1 : [object HTMLParagraphElement], 
   2 : [object HTMLParagraphElement], 
   3 : [object HTMLParagraphElement], 
   4 : [object HTMLParagraphElement], 
   5 : [object HTMLParagraphElement], 
   6 : [object HTMLParagraphElement], 
   7 : [object HTMLParagraphElement], 
   8 : [object HTMLParagraphElement], 
   9 : [object HTMLParagraphElement], 
   // 以下はプロトタイプオブジェクトから継承されるプロパティ
   init : function (selector, context) { ・・・・(以下略)

此処で分かることは、以下の諸点です。

  • setArray(array) メソッドは、$("p") インスタンスオブジェクトのプロパティを、プロパティ名 0 から順に、引数とした array 配列の各要素で置換しています。
    実際の setArray メソッドの引数は elems( elems はその要素を DOM Elements とする配列 ) ですから、DOM Elements が順番にオブジェクトのプロパティに追加されることが分かります。
  • 因みに対象オブジェクトのプロパティ名 n よりも多い要素数 m を有する配列を引数にして、同じメソッドを履行してみたところ、0 から n-1 迄のプロパティが置換され、n から m-1 迄のプロパティが追加生成されました。
  • setArray() メソッド適用によりそのプロパティが一部上書きされてしまったところの、当該メソッド適用前の $("p") オブジェクトは、別途定義されている prevObject() メソッドによって、prevObject : [object Object] に格納されています。
  • 序でに触れておけば、get() メソッドはその実行対象となった jQuery インスタンスオブジェクトのプロパティの内、プロトタイプオブジェクトを参照しないプロパティの中で、その名前が 0 から始まる連番となっているプロパティ値だけを抽出する役割を担っています。
    なお、このメソッドではプロパティ名は抽出されません。

▲ToTop

 

■ コメントの投稿 ■

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

●トラックバック●

■トラックバックURLはこちら■
http://hkom.blog1.fc2.com/tb.php/691-1327f56a

●参照元一覧●

<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が開きます。

200902250127