كشف غموض $ بإطار عمل jQuery


السلام عليكم و رحمه الله تعالى و بركاته

اكثر ما كان يحيرنى فى اطار عمل jQuery هو التالى : إستخدام ال $ – function constructor – بدون كلمه new ، و إستخدام وظائف الاطار مثل $.post بالرغم من السبب السابق ، كما توضح الامثله التاليه :

$("#result").hide();
$.post(/* arguments */);

بعد قراءه متأنيه لكود ال jQuery نسخه ال developement الملىء بالتعليقات comments ، وجدت الكود التالى :

var jQuery = window.jQuery = window.$ = function( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced' 
    return new jQuery.prototype.init( selector, context );
};

للكود السابق يقوم بتعريف function constructor بإسم jQuery و يعطيها reference بإسم $ و jQuery فى ال  global scope  لان الكود السابق كله داخل local scope ل anonymous function ، عند إستدعاء $ من ال global scope فإنها تقوم بإنشاء الوظيفه init من داخل jQuery.prototype و يمرر لها نفس العبارات التى مررت ل $🙂 ، هيا بنا ننظر ل jQuery.prototype :

jQuery.prototype = {
    init:function(selector,context){
        /* init code */
        return this;
    },
    /* rest of jQuery prototype... */
};

داخل jQuery.prototype وظائفه مثل text و show و hide و init … الخ ، وهى وظائف يمكن إستخدامها فقط اذا تم عمل كائن جديد من jQuery function constructor لأنها وظائف public ، لكن this التى داخل init لاتشير إلى الكائن jQuery عند انشاءها كائن جديد من نوع init عن طريق new init ، لذلك قام john resig مطور jQuery بمساواه init.prototype ب jquery.prototype يعنى انشاء init يقوم بإنشاء jQuery و عليها this داخل init تقوم بالإشاره الى الكائن jQuery هع هع هع😀 ، و كل وظائف jQuery ترجع الكائن jQuery لذلك يمكن عمل chaining كما وضحت فى الموضوع السابق .

jQuery.prototype.init.prototype = jQuery.prototype;

لذلك يمكنك إستخدام وظائف jQuery بعد إستخدام $ فقط كما يوضح الكود التالى :

$(); // return jQuery object 
$("#result"); // return jQuery object
$("#result").hide("slow").show("fast"); // chaining
$.show(); // Error: show is undefined
$.hide(); // Error: hide is undefined

كما ترى تلك الحيله التى فعلها جون ريسج ادت الى اعتماد الوظائف التى داخل jQuery.prototype على ماتجلبه الوظيفه init الموازيه ل $ ، لذلك فإن اخر سطرين فى الكود السابق يعطى error .

اخر شىء اود توضيحه هو استخدام الوظائف مباشره من jQuery function constructor بدون تمرير عبارات له مثل الامثله التاليه :

$.post(/* arguments... */);
$.get(/* arguments... */);

بمنتهى البساطه هذه الوظائف ماهى الا static methods يمكن استخدامها من ال constructor كما تعلمنا فى سلسله جافاسكربت الموجهه بالكائنات ، و لم اتوصل لذلك الا بعد استخدام الكود التالى :

alert($.post); // function
alert($.get); // function
var o = new $();
alert(o.post); // undefined
alert(o.get); // undefined

الاخطاء فى الكود السابق لأن الوظائف static يمكن استخدامها من ال constructor فقط اللى إسمه $ ، و لا يمكن استخدامه من الكائن o الذى تم انشائه من $ .

الأوسمة: , ,

11 تعليق to “كشف غموض $ بإطار عمل jQuery”

  1. Omar Al-Dolaimy Says:

    سأقرأها لاحقاً! تحتاج مخ صافي من الصبح🙂
    أتوقع Static حلت المشكلة صح؟

  2. mostafa farghaly Says:

    ال static حل مشكله الوظائف التى لا تعتمد على ناتج من $ مثل وظائف ال ajax ، لكنى أفضل ان تقرأها من الاول يا عمر .

  3. almhajer Says:

    مشكور اخي ولكني احاول في هذه القضية ولم تنجح معي لحد الان
    الكود الذي كتبته هو

    var BK = window.BK = window.$ = function(selector, context) {

    return new BK.prototype.init(selector, context);
    };
    BK.prototype = {
    init:function(selector, context) {
    selector = selector || document;
    return this;
    },
    hide:function() {
    this.style.display=’none’;
    return this;
    }

    };

    $(document.getElementById(“r”)).hide();
    ارجو االطلاع والشرح بالتفصيل الممل شاكرا لك تعبك وانا متابع بجد واتمنى المتابعة بهذه الدروس
    وبخاصة عن السيكتور والكيوري

  4. mostafa farghaly Says:

    انت نسيت تساوى ال bk.prototype بال init.prototype لذلك ، عند انشاء init جديد عن طريق return new init فإن this فى هذه الحاله تشير إلى init و يترتب على ذلك عدم امكانيه استخدام وظائف ال bk ، و لكى نحل هذه المشكله نقوم بإضافه الكود التالى
    BK.prototype.init.prototype = BK.prototype
    راجع المقاله ثانيا
    بعد اضافه هذا الكود ، انشاء init هو اساسا انشاء BK
    شكرا لتفاعلك ، مع العلم ان البرمجه الموجهه فى الجافاسكربت غريبه فعلا و معقده الى حد ما ، لكنها شيقه جدا .

  5. almhajer Says:

    شكرا جزيلا وبارك الله فيك بصراحة ماقصرت تسلم الايادي صحيح المشكلة انحلت
    وامنياتي في اطار دورسك ومجهودك الكبير تحط مثال فعلي على العناصر الهوتمل انا ا فضل الكود
    التطبيقي وبارك الله فيك وهذا الكود لاي ملاحظة يريت تدونها وبوركت واتمنى من كل قلبي ان تتابع الدروس بصراحة انا استفدت منها بي كثير والله يجعلها في ميزان حسناتك
    [php]

    [/php]

  6. almhajer Says:
  7. almhajer Says:

    شكل المدونة فيه خلل برمجي
    var BK = window.BK = window.$ = function(selector, context) {
    return new BK.prototype.init(selector, context);
    };

    (function() {
    BK.prototype = {

    init:function(selector, context) {
    this.selector = selector || document;
    return this;
    },
    hide:function(type) {
    this.selector.style.display = type || ‘none’;
    return this;
    },

    css:function(css) {
    this.selector.style.cssText = css || ”;
    }
    /* rest of BK prototype… */
    };
    }());

    BK.prototype.init.prototype = BK.prototype;
    $(document.getElementById(‘r’)).hide(‘block’).css(‘height:400px’);

  8. عمر الدليمي Says:

    بعد سنة، ولا زال الموضوع يحمل نوعاً من الغموض لدي!،
    الJavaScript لديها بعض المميزات المعقدة وتحمل كثيراً من الـRecursive Definitions!،
    مثلا:
    Object هو Class, Function وObject في نفس الوقت!، فلديه .prototype والذي هو من نوع Object كذلك!، prototype لديه أيضاً prototype!، أليست هذه المزايا تسهل سوء إستخدام اللغة بالرغم من قوتها!،
    أنا أستخدم الميزات هذه في حذر تام، وعلى ضوء ما أعرفه في لغات البرمجة الأخرى، أحاول محاكاة الميزات في JavaScript، أما من ناحية الDOM فلا أقترب من Native Methods مستعيضاً عنها بjQuery.

    • mostafa farghaly Says:

      @عمر الدليمى : ربما الغموض الذى لديك لأنك لا تفهم ال JavaScript Core بنسبة 100% ، قوة الجافاسكربت فى طريقة عمل ال Function التى ترث خواصها من لغة ال Scheme و Self ، لن أفهم جيدا هذه الجملة “Object هو Class, Function وObject في نفس الوقت!” ، الجافاسكربت Class Free لاتحتوى على Class construct لانها ليست classic inheritance لإعتمادها على prototypal inheritance ، لعلك تقصد كل كائنات اللغة ترث من Object ، اما النقطه الخاصة بإن Object.prototype يعطيك كائن من نوع Object فهذا طبيعى ، لأن هذا الكائن يحتوى على وظائف ال Object التى ترثها جميع الكائنات الأخرى ، انظر هذا الامثله Object.prototype يعطيك الكائن الذى يحتوى على وظائف الكائن Object التى ترثه كل الأنواع الأخرى ، Array.prototype يعطيك كائن يحتوى على وظائف Array ، و يمكنك الوصول ل Array function constructor عن طريق Array.prototype.constructor اللى هو أصلا يساوى Array😐 ، و Array.prototype لا يحتوى على وظائفه فقط بل يحتوى على الوظائف الموروثه أيضا😐 ، مثلا Array ترث من Object الوظيفه hasOwnProperty التى تقبل إسم خاصيه و توضح هل هى موروثة أم لا ، و عليه فإن Array.hasOwnPropert(“push”) ينتج عنه true لانها موجوده فى ال Array.prototype ، اما Array.hasOwnProperty(“hasOwnProperty”) يعطيك false ، لأن ال Array يرث الوظيفه hasOwnProperty من Object و عليه فإن Object.hasOwnProperty(“hasOwnProperty”) يعطيك true .

      اما ال DOM فهى ليست جزء من الجافاسكربت ، هى Standard موجود فى لغات كثير جدا للتعامل مع ال XML DOCs ، و موجود مجرد extention للجافاسكربت كغيره مثل ال BOM و XPath evaluation و XSLT Processor و CSS Selectors و غيرهم ، لكن عدم إستقراره من متصفح لاخر هو الذى ساعد على إنشاء اطر عمل مثل jQuery .

  9. احمد Says:

    هل من الممكن توضيح طريقة صناعة مكتبة مثل jquery باستخدام طريقة Chaining مع التحكم بالعناصر
    لو سمحت

  10. عمر الدليمي Says:

    بين فترة وأخرى أمر على هذه التدوينة،
    الآن بات كل شيء واضح بالنسبة لي،😀
    بفضل الله ثم التجربة الكثيرة في الجافاسكربت وخصوصاً على السيرفر.

    وبخصوص طريقة تعريف jQuery.prototype.init فأراها مبالغ بها فكان من الأفضل أن يُستعاض عنها بالتالي

    إنشاء دالة بإسم jQuery لها كل العناصر الثابتة المعروفة ك get, post, load ويكون جسمها (الكود) فيها كالتالي:

    return Object.create(jQuery.fn);

    أما jQuery.fn فهو يعتبر الPrototype لكل نواتج الإستعلام من الدوم، وفيه كل الخواص المعروفة مثل css, hide, show.

    أقول ذلك وأنا على علم بأن الكود الموجود في التدوينة قديم جداً، وربما تغير الآن في jQuery، وكذلك أعلم أن Object.create() لم تضهر للوجود إلا في وقت قريب جداً🙂.

أضف تعليقاً

إملأ الحقول أدناه بالمعلومات المناسبة أو إضغط على إحدى الأيقونات لتسجيل الدخول:

WordPress.com Logo

أنت تعلق بإستخدام حساب WordPress.com. تسجيل خروج   / تغيير )

صورة تويتر

أنت تعلق بإستخدام حساب Twitter. تسجيل خروج   / تغيير )

Facebook photo

أنت تعلق بإستخدام حساب Facebook. تسجيل خروج   / تغيير )

Google+ photo

أنت تعلق بإستخدام حساب Google+. تسجيل خروج   / تغيير )

Connecting to %s


%d مدونون معجبون بهذه: