01 | 2017/03 |  03

  1. 無料サーバー

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

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

jQueryに学ぶ Javascript の基礎(7) 組み込みクラス Array の各種メソッドに apply() メソッドを適用する──jQuery解読(40)

組み込みクラス Array の全てのメソッドに apply() メソッドは適用出来るか?

直前のエントリイ において、Array.prototype.push() メソッドへの apply() メソッドの適用について考えてみました。また、その中で関連して使用した jQuey().get() メソッドについては、こちら ( jQuery()の挙動を解読する。(11) 簡単なインスタンスメソッドいくつか──jQuery解読(19) ) で解読しました。

これらのエントリイで学習したことは、組み込みクラス Array の push() メソッドと slice() メソッドに、apply() 又は call() メソッドを適用することでした。言い換えれば、jQuery インスタンスオブジェクトに対して、組み込みクラス Array の push() メソッドあるいは slice() メソッド を apply() または、call() することでした。

さて、組み込みクラス Array の2つのメソッドに appy() / call() メソッドが適用できるということは、Array の他のメソッドに対しても apply() / call() メソッドが適用出来るのではないか、と期待しても不思議ではありません。

そこで早速それを試してみたところ、確かにそれが可能であることが分かりましたので、以下にその検証過程を詳らかにします。

▲ToTop

Array クラスのメソッドリスト

Array クラスのメソッドにはよく知られているように次のようなものがあります。

join()、reverce()、sort()、concat()、slice()、splice()、push()、pop()、unshift()、shift()、toString()、toLocalString()

この他に Firefox1.5 以降に実装されている Javascript1.6 以降で使用可能な indexOf()、lastIndexOf()、forEach()、map()、filter() などがありますが、これらは標準にはなっていないので、ここでは検証対象外とします。

まず、オブジェクトのプロパティにとってその並び順に意味はありませんから、並び順に作用する Array クラスのメソッド ( reverce、sort ) に対する apply() メソッドの適用は、検証から除外します。

残ったメソッドは 10 種類になりますが、検証はメソッドの作用内容から次のグループに分けて行います。

  1. push()、pop()、unshift()、shift()
  2. slice()、concat()、splice()
  3. join()、toString()、toLocalString()

検証の方法

jquery.1.3.2 をインクルードした Local HTML ファイルを FireFox3.x で開き、 Firebug を走らせながら、そのコンソールウィンドウに任意のコードを入力し、結果表示を観察して検証を行いました。また、検証に際しては以下のプロパティ一覧ユーティリティを使用しました。

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

▲ToTop

push()、unshift()、pop()、shift()

jQuery().setArray() インスタンスメソッドにおいて push() メソッドが利用されていたことから推測できることは、これらのメソッドに apply() / call() メソッドを適用することは、オブジェクトに対して array like な配列を追加又は削除する働きを持つだろう、ということです。

以下にそれらの検証過程と結果を記します。

unshift()
 /*++++++ unshift() +++++*/
 // unshift 関数に apply(obj,[array])メソッドを適用する
 Array.prototype.unshift.apply ( obj,[ "test",100,["test",500] ] );
 // 適用結果を一覧する
 getProp(obj) // 結果 "a : 1,2,3, b : function (x, y) { return x + y; },
  c : object, d : [object Object], 0 : test, 1 : 100, 2 : test,500, length : 3"

以上の結果を見るとこれは push() メソッドの場合の
   Array.prototype.push.apply ( obj, [ "test", 100, ["test",500] ] );
と同一の結果になることが分かります。

つまり、2 つの異なるメソッドの効果が同一となるのは、配列と異なってオブジェクトの場合には、プロパティの並び順に意味はありませんから、最後に要素を追加する push() であれ、最初に要素を追加する unshift() であれ、作用効果が同様になると考えられます。

▲ToTop

次に、配列から要素を削除する pop()、shift() メソッドを調べてみます
 /*++++++ pop().apply() or shift().apply() の検証 +++++*/
 // obj 再定義
 var obj = {
  "a":[1,2,3],
  "b":function(x,y){return x+y},
  "c":"object",
  "d":{x:789,y:321}
 };
 // pop 又は shift メソッドに apply(obj) 又は call(obj) メソッドを適用する
 Array.prototype.pop.apply ( obj ); /*又は*/ Array.prototype.shift.call ( obj );
  /*あるいは*/
 Array.prototype.pop.call ( obj , "" ); /*又は*/ Array.prototype.shift.apply ( obj , [] );
 // 適用結果を一覧する
 getProp(obj) // 結果 "a : 1,2,3, b : function (x, y) { return x + y; },
 // c : object, d : [object Object], length : 0"

以上から分かることはこの操作では何も変化しないということです。

ところが objに「配列のような」プロパティが存在する場合に pop().apply(obj) やshift().call(obj)を適用すると、事態が変わります。

 /*++++++ array like なプロパティがある obj に対して、
 pop 又は shift メソッドを apply(obj) 又は call(obj) する +++++*/
 // obj 再定義 ( array like プロパティを含ませる )
 var obj = {
  "a":[1,2,3],
  "b":function(x,y){return x+y},
  "c":"object",
  "d":{x:789,y:321},
  0:"test",
  1:100,
  2: ["test",500] 
 };
 // pop() 又は shift() メソッドに apply(obj) か call(obj)メソッドを適用する
 Array.prototype.pop.call ( obj ); /*又は*/ Array.prototype.shift.apply ( obj ); /*など*/。
 // 適用結果を一覧する
 getProp(obj) // 結果 "a : 1,2,3, b : function (x, y) { return x + y; },
  c : object, d : [object Object], 0 : test, 1 : 100, length : 2"
  // array like なプロパティの、最後のそれ( 2 : test,500 )が削除されたことが分かる。

 // 上記の後に再度 pop() 又は shift() メソッドに apply(obj) メソッドを適用する
 Array.prototype.pop.apply ( obj ); 又は Array.prototype.shift.apply ( obj );
 // 適用結果を一覧する
 getProp(obj) // 結果 "a : 1,2,3, b : function (x, y) { return x + y; },
 // c : object, d : [object Object], 0 : test, length : 1"
  //  array like なプロパティの、最後のそれ( 1 : 100 )が削除されたことが分かる。

以上をまとめると、次のようになります。

  1. obj オブジェクトに array like なプロパティがある場合には、 Array.prototype.pop.apply ( obj ) 又は Array.prototype.shift.apply ( obj ) を実行すると、当該の array like なプロパティの 1 つを削除する。その削除対象は pop でも shift でも同様に、最大整数のプロパティ名を持つプロパティとなる。
  2. 一方、obj オブジェクトに array like なプロパティが存在しない場合には、 Array.prototype.pop.apply ( obj ) 又は Array.prototype.shift.apply ( obj ) を履行しても obj に何の変化も生じない。

▲ToTop

slice()、concat()、splice()

jQuery().get() では Array.prototype.slice.call( this ) によって this に格納されている DOM Elements を取り出しています。

これを踏まえて、上と同様にカスタムオブジェクトに対して Array.prototype.concat.call( ) 及び Array.prototype.splice.call( ) を適用した場合に、意味のある結果が得られるのかどうかを検証してみます。

Array.prototype.slice.call( obj )

最初に jQuery().get() で使用されている slice() メソッドについて改めて記しておきます。

 // obj 定義
 var obj = {
  "a":[1,2,3],
  "b":function(x,y){return x+y},
  "c":"object",
  "d":{x:789,y:321},
  0:"test",
  1:100,
  2:["test",500],
  length:3
 };

 // slice.call(obj) :結果はプロパティ値を要素とする 配列になるので、
 // toString() メソッドで要素を取り出すことにする。
 Array.prototype.slice.call(obj).toString(); // 結果 "test,100,test,500"

3 つの array like なプロパティ値だけをオブジェクトから取り出せることが分かります。

jQuery().get() の場合には jQuery() オブジェクトの array like なプロパティ値は DOM Elements ですから、 jQuery().get() によって当該 DOM Elements が「取り出せる」ことになります。(詳細は こちらに まとめてあります。)

Array.prototype.concat.apply( obj , [array] )
 // obj 定義
 var obj = {
  "a":[1,2,3],
  "b":function(x,y){return x+y},
  "c":"object",
  "d":{x:789,y:321}
 };

 // Array.prototype.concat.apply( obj , [array] ) はオブジェクトを
 // 返すので、concat.apply() メソッドの return 値を ret に代入する。
 var ret = Array.prototype.concat.apply( obj, [ "test",100,["examine",500],{} ] )
 // ret オブジェクトを一覧する
 getProp(ret) // 結果 "0 : [object Object], 1 : test, 2 : 100, 3 : examine, 4 : 500, 5 :  [object Object]"

結果を見ると、生成されたret オブジェクトは obj オブジェクトを最初のプロパティ値とし、続けて apply() メソッド第 2 引数配列の各要素を順に(配列がある場合にはその要素に分解して)プロパティ値とする、全体として array likeなプロパティによって構成されることが分かります。

つまり、concat() メソッドに apply( obj,[array] ) メソッドを適用すると、元 obj オブジェクトと第 2 引数の [array] 配列オブジェクトを、その配列内に配列がある場合にはそれを全て要素に分解してから、全体として array like な配列をプロパティとする、新たなオブジェクトが再構築されるわけです。

なお jquery.js(ver 1.3.2) 内に concat は 4 カ所ありますが、それらがここで触れた方法と目的で使われているのかどうかについては、まだ検証していません。

Array.prototype.splice.apply( obj , [array] )
 // obj 定義
 var obj = {
  "a":[1,2,3],
  "b":function(x,y){return x+y},
  "c":"object",
  "d":{x:789,y:321},
  0:"test",
  1:100,
  2:["test",500],
  length:3
 };
 /*---------(1) 単純に新規プロパティを追加するケース-------------------------*/
 // splice.apply(obj,[array])
 Array.prototype.splice.apply( obj, [ obj.length,0,1000,["today","yesterday"],{} ] )
 // 適用結果を一覧する
 getProp(obj) // 結果 "a : 1,2,3, b : function (x, y) { return x + y; },
 // c : object, d : [object Object], 0 : test, 1 : 100, 2 : test,500, 
 // length : 6, 3 : 1000, 4 : today,yesterday, 5 : [object Object]"

 /*-- (2) 一部の既存プロパティを削除し、かつ新規プロパティを追加するケース --*/
 // splice.apply(obj,[array])
 Array.prototype.splice.apply( obj, [ 0,2,1000,["today","yesterday"],{} ] )
 // 適用結果を一覧する
  getProp(obj)  // 結果 "a : 1,2,3, b : function (x, y) { return x + y; },
  // c : object, d : [object Object], 0 : 1000, 1 : today,yesterday,
  // 2 : [object Object], 3 : test,500, length : 4"

splice() メソッドは配列に要素を追加/削除するための、最も汎用的な関数です。上の例により、これをオブジェクトに apply することによって、array like なプロパティを必要なだけ追加出来ることが分かります。

例(1)では、第 2 引数である配列の第 1 要素の obj.length により開始番号を設定し、第 2 要素の 0 により何も削除しないことを指示し、1000 以降の 3 つの配列要素を obj オブジェクトに追加しています。

例(2)では、開始番号を 0 、削除数を 2 と指定することにより、既存の 2 つのプロパティ {0 : test, 1 : 100}を削除し、第 2 引数である配列の、第 3 要素から第 5 要素までの 3 つの要素を、新たなプロパティとして obj オブジェクトに追加し{ 0 : 1000, 1 : today,yesterday, 2 : [object Object] }、残存している既存のプロパティ値 "test,500" の要素番号をずらして {3 : test,500} とし、最後に 2 つの要素を削除し、3 つの要素を追加した結果として length 値を 4 としています。

つまり、splice() メソッドを obj オブジェクトに apply すると、obj オブジェクトに対して pop や unshift よりも自在に( 位置を指定してプロパティを部分的に削除することも可能 )、array like なプロパティを付加することが出来ることが分かります。

因みに jquery.js(ver 1.3.2) 内に splice は 3 カ所ありますが、それらがここで触れた方法と目的で使われているのかどうかについては、まだ検証していません。

▲ToTop

join()、toString()、toLocalString()

toString() 及び toLocalString() については、call(obj) を適用して意味のあるreturnは得られませんでしたが、join() については以下のように意味のある結果を得ることが出来ました。

Array.prototype.join.call( obj )
 // obj 定義は同上とする

 // join.call(obj, arg)
 Array.prototype.join.call( obj, " : " )
  // 結果 "test : 100 : test,500"
 // [ "test", 100, ["test",500] ].join(" : ") と同一の結果となっている。

上を見ると join.call(obj, arg) は obj オブジェクトの中の その他プロパティを無視しつつ、array like なプロパティ値だけを文字列として取りだし、arg 文字(列)で接続する機能を持っていることが分かります。

但し、そのような機能を必要とする状況にはどんなものがあるのか、想像すら出来ません。つまりこのメソッドは余り使い道がないような気がします。

 

● コメント ●

承認待ちコメント ()

このコメントは管理者の承認待ちです

● コメント ●

承認待ちコメント ()

このコメントは管理者の承認待ちです

● コメント ●

承認待ちコメント ()

このコメントは管理者の承認待ちです

● コメント ●

承認待ちコメント ()

このコメントは管理者の承認待ちです

● コメント ●

承認待ちコメント ()

このコメントは管理者の承認待ちです

■ コメントの投稿 ■

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

●トラックバック●

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

●参照元一覧●

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

200903012228