rightjsの継承メカニズムを解読する1

5525 ワード

継承メカニズムの出現はjavascriptが大規模な開発の敷居に達したことを示している.Javaのように、その工業化に対応するために、設計モデルを美しく発揮します!javascriptのコードを何千行も何万行も強制できるものはありますか?フレームワーククラスライブラリが補助ツールであるほか、ゲームという贅沢な娯楽である.光表示インタフェース、操作インタフェース、評価システムも細分化できます.もう一つEXTのようにHTMLやCSSに代わる純javascriptの機能を利用してウェブページを開発するのも膨大なものです.巨大なものはモジュール化され、各モジュールは必ずしも1種類ではないが、クラスはその不可欠な構成要素である.Javascriptの目的はWebページのインタラクションを実現することであるため、これらのクラスの大部分はDOM要素を操作する内容を含んでおり、ノードを生成したり、DOMツリーのどこかに挿入したり、スタイルを設定したり、イベントをバインドしたり、削除したり......など様々である.多くの操作がクラスの方法として存在する場合、より良い名前を付けるのが適切です.各クラスの連動の面では、ブラウザが提供するイベントメカニズムよりも有名なオブザーバーモードが魅力的であり、少なくともモジュールのデカップリングの面で優れています.例えば、次のコードは3つのモジュールに関連しています.


        this.keyboard

        .onLayoutChange(this.progress.setLayout.bind(this.progress))

        .onKeyPress(this.field.keyPressed.bind(this.field));


キーボードの外観が変更されると、上の進捗バーも変更され、キーが押されると、表示領域も応答します.暗黙的には、最後の操作が別の操作を刺激します.


keyPressed: function(key_code) {

    var element = this.pullElement(key_code);

    

    if (element) {

      element.droppinFx.cancel();

      element.highlight('#AFA', {

        duration: 160, onFinish: element.remove.bind(element)

      });

      

      this.fire('hit', element.innerHTML);//★★★★

    }

  },


jQueryでシミュレーションするのは実際には難しい.


    this.settings.layouts.change(function(){

        var layout = $(this).val();

        var keynames = ths.keyboard.setLayout(layout);

        ths.progress.setLayout(keynames)

    });


2番目のonKeyPressは本当に存在するイベントではなく、他のイベントコールバックによって実現されます.


  hightlightKey: function(event) {

    var key = this.keys[event.charCode] || this.keys[event.keyCode];

    if(key){

      if (!event.altKey && !event.ctrlKey && !event.metaKey) {

        event.stop();

        key.highlight({duration: 160});

        this.fire('key_press', event.charCode || event.keyCode);//   onKeyPress

      }

    }

 },


しかし,ここでのthisは要素ノードではなく,イベントメカニズムはこれに対して無力であり,オブザーバモードを導入する必要がある.もし本当にこのような設計が必要であれば、私たちはクラスの存在を要求し、少なくとも観察者モードではパブリッシャオブジェクトとサブスクライバオブジェクトが要求されます.mootoolsが台頭できるのは、強力な継承メカニズムを提供し、より複雑なプログラミングを実現するためです.EXTのような複雑なものはなおさらです.rightjsは上記のフレームワーククラスライブラリほど有名ではありませんが、後生恐れられ、著者もその長所を吸収しているに違いありません.その継承メカニズムは先輩よりはるかに複雑で強く、それが私がそれを学ぶ理由です.


var Class = function() {

  //    ,       ,      ,         

  var args = $A(arguments), properties = args.pop() || {}, parent = args.pop();



  // basic class object definition

  //    

  function klass() {

    return this.initialize ? this.initialize.apply(this, arguments) : this;

  };



  //         

  if (!args.length && !isHash(properties)) {

    parent = properties; properties = {};

  }



  //           ,     

  $ext(klass, Class.Methods).inherit(parent);



  // catching the injections

  //        extend、include  

  $w('extend include').each(function(name) {

    if (properties[name]) {

      var modules = properties[name];

      klass[name].apply(klass, isArray(modules) ? modules : [modules]);

      delete(properties[name]);

    }

  });

  //             

  return klass.include(properties);

};


姿はPrototypejsとあまり違わないので、仕方がない.英雄の見たことは少し同じで、みんなAlex Arnellの実現を改良するのが好きだ.$extメソッドがあります.




//  Prototype extend,       ,   EXT  

function $ext(dest, src, dont_overwrite) {//   undefined

  var src = src || {}, key;



  for (key in src)

    if (dont_overwrite !== true || typeof(dest[key]) === 'undefined')

   //   true              ,      

      dest[key] = src[key];



  return dest;

};


印象の$の冒頭のメソッド名定義は初期のPrototypejsフレームワークではあまり現れず、いくつかしかなく、mootoolsに写してから、mootoolsはそれを大きく発揚し、逆にPrototypejsに影響を及ぼした.私はこのような命名方式が嫌いで、それは本当に自分をPHPと見なしますか?!
javascriptのObjectオブジェクトかどうかを検出するisHashメソッドがありますが、jQueryのisPlainObjectには及ばない


  isHash = function(value) {

    return to_s.call(value) === '[object Object]';

  };



// IE ,           DOM  ,         

  if (isHash(document.documentElement)) {//   [object HTMLHtmlElement] IE [object Object]

    isHash = function(value) {

      return to_s.call(value) === '[object Object]' &&

        value !== null && typeof(value) !== 'undefined' &&

        typeof(value.hasOwnProperty) !== 'undefined';

    };

  }


jQueryのisPlainObjectはDOMオブジェクトだけでなく、カスタムクラスも区別できます.


        isPlainObject: function( obj ) {

            // Must be an Object.

            // Because of IE, we also have to check the presence of the constructor property.

            // Make sure that DOM nodes and window objects don't pass through, as well

            if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {

                return false;

            }



            // Not own constructor property must be Object

            if ( obj.constructor

                && !hasOwnProperty.call(obj, "constructor")

                && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {

                return false;

            }



            // Own properties are enumerated firstly, so to speed up,

            // if last one is own, then all properties are own.



            var key;

            for ( key in obj ) {}



            return key === undefined || hasOwnProperty.call( obj, key );

        },


次のセクションではClassについて説明します.次の操作を続行するには、サブクラスに多くの静的メソッドを追加するMethodsメソッドです.