01 | 2017/03 |  03

  1. 無料サーバー

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

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

jQuery()の挙動を解読する(24) jquery.js 1.3.2 における jQuery 定義コードを分析する──jQuery解読(36)

ver1.3.2 における jQuery インスタンス生成コード

jQuery オブジェクトの定義コードは、1.2 → 1.2.1 → 1.2.2 と 1.2x で頻繁に改訂されました。2008年1月から2月に掛けて根幹部分の定義が立て続けに更新されたのです。しかしその後は 1.3.2 まで1.2.2の定義が継承されており、定着した感があります。(以下行数は ver 1.3.2 による)

ver 1.2.2 の変更によって(25行のコメントにもあるように)、jQuery 関数オブジェクトは そのプロトタイププロパティである init() メソッドをコンストラクタとするインスタンスを受け取るものと、定義されました。

 24: jQuery = window.jQuery = function( selector, context ) {
 25:  // The jQuery object is actually just the init constructor 'enhanced'
 26:  return new jQuery.prototype.init( selector, context ) :
 27: },

ここで興味深いことは、ver1.2.1までと異なって、jQuery 関数オブジュクトそれ自体がコンストラクタなのではない、ということです。コンストラクタは jQuery のプロトタイプオブジェクトの init メソッドになっています。

さて、最初はこの変更されたコードの意味及び変更の意義が分かりませんでした。そこで改めて new 演算子やコンストラクタについて学び直さなければなりませんでした。分かっていたつもりなのに、結局半可通だったことを再認識させられたのです。

通常の説明におけるコンストラクタ、インスタンス、new 演算子(復習)

通常コンストラクタ、インスタンスの学習コード等では、例えば次のような例示が行われます。

 var Rectangle = function (x,y){ this.x=x; this.y=y; }
 Rectangle.prototype.area= function(){ return this.x * this.y };
 Rectangle.prototype.outer = function (){ return 2*(this.x + this.y) };
 var inst = new Rectangle(2,3);
 inst.area();  // result = 6
 inst.outer(); // result = 10

この例では、Rectangle コンストラクタ関数から生成されたインスタンスオブジェクト( inst )は、そのコンストラクタオブジェクト ( Rectangle ) に関連づけられたプロトタイプオブジェクト ( Rectangle.prototype ) からプロパティを継承する、と説明されます。

つまり、プロトタイプオブジェクトのプロパティである area() メソッドや outer() メソッドが inst オブジェクトに継承されるので、上記例の最後の2行のような結果が取得出来る、という説明です。

次に、Javascript第5版によれば「 new 演算子は、(1)空のオブジェクトを生成し、(2)そのオブジェクトへの参照をキーワード this に代入し、(3)コンストラクタ関数の prototype プロパティをそのオブジェクトの prototype として設定し、(4)そのオブジェクトのメソッドとしてコンストラクタ関数を呼び出す」と説明されています。

上記の Rectangle に沿って言えば、(1)空オブジェクト(仮に obj とする)を生成し、(3) this の参照先を obj とし( this = obj )、(2) this.prototype を設定し ( この prototype 参照先は Rectangle.prototype に同じなので this.area()、this.outer() が設定され )、最後に (4) Rectangle.apply( this, [x,y] ) を実行することなります。

注目すべきことは、コンストラクタ関数の実行は最後に行われるのであって、その前にプロトタイププロパティが new 演算子によって新たに生成されたオブジェクトに設定されることです。もう一度順番を書けば
  (1) obj 生成
  (2) this = obj 設定
  (3) this.prototype = Rectangle.prototype 設定
  (4) Rectangle.apply ( this, [x,y] ) 実行
となります。

jQuery 定義コードにおけるコンストラクタ、インスタンス、new 演算子

次に同じ事を jQuery 定義コードに適用してみます。19行の new 演算子とそれに続く init 関数は
 (1) obj 生成
 (2) this = obj 設定
 (3) this.prototype = jQuery.prototype.init.prototype 設定
 (4) jQuery.prototype.init.apply(this, [selector, context]) 実行
を行うことになります。

さて、ここに登場する jQuery.prototype.init.prototype の値は何なのでしょうか? 一体、initメソッドのプロトタイププロパティとはどんな内容なのでしょうか? それはどこで定義されているのでしょうか?───こんな疑問が湧いてきます。

そしてその答えを探したところ、それは ver 1.2.2 以降で新設された次の2行にありました。

540: // Give the init function the jQuery prototype for later instantiation
541: jQuery.prototype.init.prototype = jQuery.prototype;

つまり、jQuery.prototype.init メソッドのプロトタイプは jQuery 関数オブジェクトのプロトタイプを参照し、それに等しくなります。

こうして、jQuery 関数オブジェクトはコンストラクタ init 関数から return される実行結果 ( それは this であったり、様々な指定によって生成された[obj]であったり、[selector]であったりする ) を受け取ると共に、jQuery.prototype プロパティに定義された様々なメソッドやプロパティを継承することになります。

init は従来通り初期化関数として作動し、かつ jQuery.prototype に設定された様々なメソッドやプロパティは jQuery 関数オブジェクトに継承されるわけです。

それにしても何故、jQuery.prototype オブジェクトのメソッドである init() をコンストラクタとするのでしょうか?

1.2.1までの方法を敢えて変更した理由はどこにあるのでしょうか?「インスタンスを生成してから init() メソッドを起動し、その return を jQuery オブジェクトが受け取る」という従来の方法を変えた理由が分かりません。極めて合理的なコードだと思っていたのですが、1.2.2 のコードの方が何らかのメリットがなければそうしないでしょうから、是非とも変えた理由を探りたいのですが、力及ばず、残念ながら解明出来ていません。

そこで改めて コード「 jQuery.prototype.init.prototype = jQuery.prototype 」を考えてみる

この式は「循環参照」問題を引き起こすのではないか、と言うことに気がつきました。

右辺の prototype オブジェクト内には、当然 init プロパティがあり、その init プロパティは prototype プロパティがあります。つまり jQuery.prototype.init.prototype が右辺の prototype オブジェクト内に存在しています。

以下その繰り返しになります。

その結果無限にこれが繰り返され、メモリが消費されるのではないかと考えられます。

実際、或るサイトでそのことを確認したところ下図のように際限なくinit.prototype 内にinit.prototype が内包されていることが確認できました。

どこまで行っても際限なく繰り返される init.prototype 循環にコードとして問題はないのだろうか?

 

■ コメントの投稿 ■

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

●トラックバック●

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

●参照元一覧●

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

200801272337