Prototype.jsの$()がすること

確認したバージョンは1.6.0.3。

$()

Prototype.jsで拡張したelementオブジェクト(の配列)を返す関数。
引数が複数の場合は、再帰的に自身を呼び出し配列にセット。その配列をreturn。
引数が一つで文字列であればidとみなしてelementオブジェクトを取得する。
Element.extendメソッドで拡張したelementをreturn。

function $(element) {
  if (arguments.length > 1) { // 引数が複数の場合
    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
      elements.push($(arguments[i])); // 自身を呼び出した結果を配列に入れる
    return elements;
  }
  if (Object.isString(element)) // 文字列の場合はIdとみなす
    element = document.getElementById(element);
  return Element.extend(element); // メソッドを追加してreturn
}

Element.extend()

elementオブジェクトを拡張(メソッド追加)するメソッド。
タグごとにDOMオブジェクトが定義されているブラウザの場合は何もしない。
(あとでElement.addMethodsメソッドで直接DOMオブジェクトを拡張するため)
引数にとったelementがすでに拡張されている場合とElementノードではない場合とwindowオブジェクトの場合は何もしない。

Element.extend = (function() {
  // タグごとにDOMオブジェクトが定義されている場合
  if (Prototype.BrowserFeatures.SpecificElementExtensions) 
    return Prototype.K; // 引数をそのまま返すメソッドとする

  var Methods = { }, ByTag = Element.Methods.ByTag;

  var extend = Object.extend(function(element) {
    // すでに拡張されている、elementノードでない、windowオブジェクトの場合...
    if (!element || element._extendedByPrototype || 
        element.nodeType != 1 || element == window) return element; //そのまま返す

    var methods = Object.clone(Methods), // 複製する
      tagName = element.tagName.toUpperCase(), property, value;

    // 特定のタグに対してのメソッド追加
    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);

    for (property in methods) {
      value = methods[property];
      // valueが関数で、elementにpropertyが定義されていない場合...
      if (Object.isFunction(value) && !(property in element))
        // 第一引数に自動でthisをとるメソッドにして返す
        // 実際にメソッドが呼ばれるときはthis==elementとなる
        element[property] = value.methodize(); 
    }

    element._extendedByPrototype = Prototype.emptyFunction; // 拡張済みのフラグをつける
    return element;

  }, {
    refresh: function() {
      // 全てのタグに対してメソッドを拡張する (Safariは必要なし)
      if (!Prototype.BrowserFeatures.ElementExtensions) {
        Object.extend(Methods, Element.Methods);
        Object.extend(Methods, Element.Methods.Simulated);
      }
    }
  });

  extend.refresh();
  return extend;
})();

無名関数を作成してすぐ実行しているので、その戻り値がElement.extendにセットされる。
Methodsは追加されるメソッド群、ByTagはタグごとに追加されるメソッド群。
extend(ローカル変数)が、Element.extendの本体。
extend.refreshは全てのタグに対して追加するメソッドをMethodsに追加するメソッド。
extendとextend.refreshは共にMethodsを参照するクロージャのため、
Methodsを拡張することで追加されるメソッドを変更することができる。

  • Obejct.extend : 第一引数に第二引数のプロパティを追加して返すメソッド。
  • Object.clone : シャローコピーを作成して返すメソッド。
  • Prototype.K : 引数をそのまま返すメソッド。
  • Prototype.emptyFunction : 何もせず何も返さないメソッド。
  • Function.methodize : 第一引数にthisをとるメソッドにして返すメソッド。