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

6900 ワード

仏経には功不唐寄付という言葉がある.すべての努力の効果は必ずしも今に生まれるとは限らず、未来に生まれるかもしれませんが、あなたがすれば、それはきっと意味があります.私达の心理状态は少し穏やかで、次第にそれを推进して、次第にそれを改良して、未来に対してきっととても意义があります.
ある種のライブラリやフレームワークを狭隘に支持する人もいるが、実は良いものは互いに浸透している.jQueryのようにDOMの操作を提供していますが、それだけでは十分ではありません.バックグラウンドの添削でフロントを見ないでください.フロントの展示はとても多彩です.楽屋もそんなに退屈ではありません.もちろん無能な人にはどうでもいいです.***このようなIT生涯は本当に30歳までしか耐えられない.私たちは一つのものに集中しています.他の同じタイプの製品は非常に参考価値があり、私たちの思考を広げることができます.例えばjavascript界を最初に制覇したPrototype.jsは、railsの補助プロジェクトとして誕生した.本当のすべてが対象のルビーのデザインだからjsは当時天下を横切ったが,誰も敵わなかった.その多くのメソッド名はruby標準ライブラリから取得されていることがわかります.Base 2のような強力なライブラリもPrototypeから来ていると思います.jsは多くのインスピレーションを吸収した.MootoolsはPrototypeと呼ばれています.js,フレームワークはPrototypeであるが,多くの実装はBase 2から変更されている.この3つはいずれも強力な継承メカニズムを持っており、どうせそのうちの1つを学んだので、他の2つには簡単に手に入ることができます.言い換えれば、寄付をしない限り、あなたの知恵の投資は無駄になりません.
西洋のオープンソース世界は非常に活発で、新興クラスライブラリは濃厚な既知の枠組みの影を持っている.rightjsがその例です.今日はその2つのモジュールについて説明して、思わず感じました.
Optionsモジュールは、パラメータの処理に特化しています.Prototypeの有名な特効ライブラリでは、すでにこのような兆候があります.MootoolsはいっそObjectに渡した.resetはこの粗雑な仕事をしに来た.どうしてこんなことをするのですか.通常、新しく生成されたクラスを構成するためにプロパティパッケージを転送し、クラスメンバー、インスタンスメンバーなどを追加し、mootools 2の青写真では、友元メンバーの構成も計画されています.これは実はmootools 1にあります.2.4ではprotect法で実現されていますが、もっとsmartにしたいと思っています.


    Options = {

    

      setOptions: function(options) {

        //       options  ,          ,     ,  Options          ,

        //            。

        var options = this.options = Object.merge(Class.findSet(this, 'options'), options), match, key;

        //    on     ,    , this.on("click",function(){})

        if (isFunction(this.on)) {

          for (key in options) {

            if (match = key.match(/on([A-Z][A-Za-z]+)/)) {

              this.on(match[1].toLowerCase(), options[key]);

              delete(options[key]);

            }

          }

        }



        return this;

      },



      //  rightjs            ,           ,             

      cutOptions: function(args) {

        var args = $A(args);

        this.setOptions(isHash(args.last()) ? args.pop() : {});

        return args;

      }

    };


以下は観察者モジュールで、その多くの方法は多くの伝参形式をサポートして、jQueryのように、論理を複雑にして、本当に気持ち悪いです.


    Observer = new Class({

      include: Options,



      /**

       * general constructor

       *

       * @param Object options

       */

      initialize: function(options) {

        this.setOptions(options);

        Observer.createShortcuts(this, Class.findSet(this, 'events'));

      },





      //this.on("click", fnCallback)

      //           ,    

      on: function() {

        var args = $A(arguments), event = args.shift();



        if (isString(event)) {

          //    $listeners          

          if (!defined(this.$listeners)) this.$listeners = [];



          var callback = args.shift(), name;

          switch (typeof callback) {

            case "string":

              name     = callback;

              callback = this[callback];



            case "function":

              var hash = {};



              // DON'T move it in the one-line hash variable definition,

              // it causes problems with the Konqueror 3 later on

              hash.e = event;

              hash.f = callback;

              hash.a = args;

              hash.r = name;



              this.$listeners.push(hash);

              break;



            default:

              if (isArray(callback)) {

                for (var i=0; i < callback.length; i++) {

                  //         

                  this.on.apply(this, [event].concat(

                  isArray(callback[i]) ? callback[i] : [callback[i]]

                ).concat(args));

                }

              }

          }



        } else {

          //              

          for (var name in event) {

            this.on.apply(this, [name].concat(

            isArray(event[name]) ? event[name] : [event[name]]

          ).concat(args));

          }

        }







        return this;

      },





      //     , Prototype observes   

      observes: function(event, callback) {

        if (!isString(event)) { callback = event; event = null; }

        if (isString(callback)) callback = this[callback];



        return (this.$listeners || []).some(function(i) {

          return (event && callback) ? i.e === event && i.f === callback :

            event ? i.e === event : i.f === callback;

        });

      },

      

      stopObserving: function(event, callback) {

        if (isHash(event)) {

          for (var key in event) {

            this.stopObserving(key, event[key]);

          }

        } else {

          if (!isString(event)) { callback = event; event = null; }

          if (isString(callback)) callback = this[callback];



          this.$listeners = (this.$listeners || []).filter(function(i) {

            return (event && callback) ? (i.e !== event || i.f !== callback) :

              (event ? i.e !== event : i.f !== callback);

          }, this);

        }



        return this;

      },



      //           ,             

      listeners: function(event) {

        return (this.$listeners || []).filter(function(i) {

          return !event || i.e === event;

        }).map(function(i) { return i.f; }).uniq();

      },

      //           

      fire: function() {

        var args = $A(arguments), event = args.shift();



        (this.$listeners || []).each(function(i) {

          if (i.e === event) i.f.apply(this, i.a.concat(args));

        }, this);



        return this;

      },



      extend: {



        //             

        create: function(object, events) {

          $ext(object, Object.without(this.prototype, 'initialize', 'setOptions'), true);

          return this.createShortcuts(object, events || Class.findSet(object, 'events'));

        },



        createShortcuts: function(object, names) {

          //     object   onLayoutChange      

          (names || []).each(function(name) {



            var method_name = 'on'+name.replace(/:/g, '_').camelize().capitalize();

            if (!defined(object[method_name])) {

              object[method_name] = function() {

                return this.on.apply(this, [name].concat($A(arguments)));

              };

            }

          });



          return object;

        }

      }

    });

    // observe    

    $alias(Observer.prototype, { observe: 'on' });


オブザーバモードは,カスタムクラスにもイベントシステムのような関連操作を持たせ,一変するとみんなが変化し,デカップリングに非常に有利である.最初のClassからOptionsからObserverまで、分解できるものをすべて分解しました.このモジュール化設計は私たちの学習に非常に有利です.jQueryのように、多くのプラグインを通じてコアライブラリの機能を補う別の道を歩んでいます.もちろん、人が多くて仕事が上手で、それは時々いくつかの優秀な方法を吸収してコアライブラリに参加しました.しかし、どんなに振り回されても、クラスライブラリの能力は限られており、このような全面的な拡張道路の枠組みとは比べものにならない.Javascriptを学ぶにはPrototypeのようなフレームワークがより大きな収穫をもたらします.