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

من إسبوعين تقريبا ألقيت محاضرة فى كلية هندسة جامعة المنصورة بعنوان Front-end engineering تحدثت فيها عن ال loadtime optimizations يمكنك تحميل الشرائح من هنا .
السلام عليكم و رحمة الله و بركاته

من إسبوعين تقريبا ألقيت محاضرة فى كلية هندسة جامعة المنصورة بعنوان Front-end engineering تحدثت فيها عن ال loadtime optimizations يمكنك تحميل الشرائح من هنا .
السلام عليكم و رحمة الله تعالى و بركاته

أعطىء Tom Van Cutsem محاضرة فى جوجل بعنوان Changes to ECMAScript ناقش فيها التغيرت التى طرأت على الجافاسكربت بعد تبنى مواصفات ECMASCript 5 و إستفاض فى نقاش ال Proxies و ال traits ، يمكنك مشاهدة المحاضرة على اليوتيوب من هنا ، هذه المحاضرة الجزء الثانى لمحاضرة upcoming changes to ECMAScript التى دونت عنها من قبل .
السلام عليكم و رحمة الله تعالى و بركاته
أعطى كل من Nicholas Zakas و Stoyan Stefanov و Ross Harmes و Julien Lecomte و Matt Sweeney محاضرة بعنوان High performance JavaScript أحتفالا بنشر كتاب O’Reilly High performance JavaScript ، الكتاب أنصح بقرائته بشدة – فصل مجانى -، يمكنك تحميل المحاضرة من هنا مباشرة 572MB عالية الجودة ، او مشاهدة المحاضرة أونلاين من هنا .
أنصح أيضا بقراءة هاذين الكتابين بشدة High performance websites و even faster web sites .
هذه المقالة ترجمة ECMA-262-3 in detail Chapter1. Executions Contexts للكاتب Dmitry A. Soshnikov
1- مقدمة
2- تعريفات
3- أنواع الكود القابل للتنفيذ
كود ال global
كود الوظائف
كود الوظيفة eval
4- إستنتاج
5- المزيد
فى هذا المقال سأقوم بذكر أنواع سياقات التنفيذ execution contexts ب ECMAScript و أنواع الكود القابل للتنفيذ المرتبط بهم .
فى كل مرة ينتقل فيها التحكم إلى كود قابل للتنفيذ فى ECMAScript فإن الكود يدخل فى سياق للتنفيذ execution context. سياق التنفيذ execution context إختصارا EC هو مفهوم تجريدى تستخدمه مواصفات ال ECMAScript لتصنيف وتمييز الأكواد القابلة للتنفيذ.
منطقيا , مجموعة من سياقات التنفيذ النشطة تقوم بتشكيل stack ، أسفل هذا ال Stack غالبا ما يكون السياق الشامل global context ، أما بالأعلى فيكون سياق التنفيذ النشط الحالى . يتم تعديل ال stack – يضاف إلى و يحذف من أعلاه – خلال الدخول إلى و الخروج من أنواع سياقات التنفيذ المختلفة .
مع هذا المفهود التجريدى لسياق التنفيذ ، نوع الكود القابل للتنفيذ executable code مرتبط به . عند الحديث عن نوع الكود فإنه من الممكن فى بعض الأوقات ان نقصد به سياق التنفيذ.
فى الأمثلة سنعرف stack سياقات التنفيذ كمصفوفة :
ECStack = [];
يتم الإضافة إلى هذا ال stack فى كل مرة عند دخول وظيفة حتى إذا إستدعت هذه الوظيفة نفسها recursively أو كانت constructor ، و إيضا عند تنفيذ كود من خلال الوظيفة eval .
هذا النوع من الكود الذى يتم تنفيذه فى مستوى البرنامج مباشرة داخل ال script tag او الذى يتم تحميلة من ملف خارجى خارج أى وظيفة ، عندما يتم بدأ تطبيق البرنامج فإن ال ECStack يبدو هكذا :
ECStack = [
globalContext
];
عند دخول كود الوظيفة (كل أنواع الوظائف) ، فإن ال ECStack يتم الإضافة عليها عناصر جديدة ، من المهم ان تلاحظ ان سياق كود الوظيفة لا يضمن سياق الوظائف الداخلية ، على سبيل المثال هذه الوظيفة تستدعى نفسها مرة واحدة فقط :
(function foo(bar) {
if (bar) {
return;
}
foo(true);
})();
التعديلات التى تطرأ على ECStack :
// عند دخول foo لأول مرة لتنفيذ الكود ECStack = [ <foo> functionContext globalContext ]; // عندما نادت foo نفسها ECStack = [ <foo> functionContext – recursively <foo> functionContext globalContext ];
كل return تقوم بالخروج من سياق التنفيذ الحالى و بالتالى يتم حذف أعلى عنصر فى ال ECStack بالتوالى من أعلى إلى أسفل . و أيضا الإستثناء الذى يتم طرحه ولا يوجد كود لإلتقاته يتسبب فى الخروج من واحد او كثر من سياقات التنفيذ حتى يتم إلتقاته و معالجته ، بعد انتهاء عمل هذا الكود فإن ال ECStack مرة أخرى يحتوى على السياق الشامل globalContext فقط حتى إنتهاء البرنامج .
الأمور أكثر إثارة عندما نتحدث عن كود ال eval ، ينشأ هنا مفهوم سياق الإستدعاء calling context السياق الذى يتم منه إستدعاء الوظيفة eval ، حيث ان التأثير الذى تحدثه الوظيفة eval مثل انشاء المتغيرات و الدوال يؤثر على سياق الإستدعاء :
eval('var x = 10');
(function foo() {
eval('var y = 20');
})();
alert(x); // 10
alert(y); // "y" is not defined
التعديلات التى تطرأ على ECStack :
ECStack = [
globalContext
];
// eval('var x = 10');
ECStack.push(
evalContext,
callingContext: globalContext
);
// eval خرجت من السياق
ECStack.pop();
// عند إستدعاء الوظيفة foo
ECStack.push(<foo> functionContext);
// eval('var y = 20');
ECStack.push(
evalContext,
callingContext: <foo> functionContext
);
// الإنتهاء من تنفيذ eval
ECStack.pop();
// الإنتهاء من تنفيذ foo
ECStack.pop();
فى SpiderMonkey محرك ترجمة الجافاسكربت الموجود فى فايرفوكس و سندربرد لغاية النسخة 1.7 من الممكن تمرير عبارة تانية للوظيفة eval لكى تمثل سياق الإستدعاء calling context ، ومن الممكن عن طرق ذلك التأثير على المتغيرات الخاصة كما يسميها البعض :
function foo() {
var x = 1;
return function () { alert(x); };
};
var bar = foo();
bar(); // 1
// تمرير سياق الإستدعاء للتأثير على المتغير الداخلى إكس
eval('x = 2', bar);
bar(); // 2
هذه المعالجة النظرية مطلوبة لمزيد من التحليل لتفاصيل المواضيع الاخرى المرتبطة بسياقات التنفيذ مثل كائن المتغير Variable object و سلسلة المدى scope chain … الخ .
القسم المقابل فى مواصفات ECMA-262-3 Execution Contexts
السلام عليكم و رحمة الله تعالى و بركاته
إنتهى Dmitry A. Soshnikov من شرح ECMAScript 262 3rd edition بلغة انجليزية واضحة لمبرمجين الجافاسكربت و هى مواصفات اللغة المبنية عليها جافاسكربت التى تعمل فى جميع المتصفحات و محركات الترجمة حاليا ، من سنحت له الفرصة و قرأ ECMA-262-3 سيجدها معقدة جدا لأنها موجهة لمصممين لغات البرمجة حتى ينتجوا مترجم يفهم لغة جافاسكربت ، أما السلسلة التى شرحها ديمترى فهى بلغة انجليزية مباشرة و سهلة الفهم للمبرمجين العادين الذين يريدون فهم أعمق لكيفية عمل الجافاسكربت خاصة الاجزاء الغامضة منها مثل ال Closure و ال Execution context و This … الخ ، السلسلة تم شرحها فى 9 فصول كالتالى بالترتيب :
Execution Contexts
Variable object
This
Scope chain
Functions
Closures
OOP: The general
OOP: ECMAScript
Evaluation strategy
و قد وعد أيضا ديميترى بشرح ECMAScript 5th edition قريبا .
أنصح بشدة قراءة هذه السلسلة لمن يريد فهم الجافاسكربت بعمق أكثر و من يريد أن ينتقل من المستوى المتوسط إلى مستوى الإحتراف.
السلام عليكم و رحمة الله تعالى و بركاته
فى الموضوع السابق ذكرت ان الوظيفة Fibonacci تنادى نفسها 21 الف و 890 مرة لتحسب رقم Fibonacci للرقم 20 ، و إذا ناديتها مرة أخرى لتحسب الرقم fibonacci للرقم 20 فإنها ستنادى نفسها 20 الف و 890 مرة أخرى
و هذا بالطبع سيؤدى إلى تعطيل ال thread الرئيسى للتطبيق لفترة من الوقت و سيؤدى إلى user experience سىء للغاية ، الوظيفة fibonacci بطبيعة الحال هى وظيفة Idempotent بمعنى ان اعطيتها نفس المدخلات -العبارات-ستعطيك نفس النتائج فى كل مرة تنادى عليها ، يمكننا تخزين هذه النتيجة فى Cache و ربطها بالمدخل بحيث إذا ناديتها مرة أخرى بنفس المدخل ستحصل على النتيجة من ال Cache إذا كانت موجودة بدلا من ان تنادى نفسها 20,890 مرة لتحصل على النتيجة ، و بذلك يمكن تقليل عدد الاستدعائات من 20,890 إلى إستدعاء واحد فقط
.
هذا هو الكود الخاص بالوظيفه fib اختصار ل fibonacci من الموضوع السابق :
function fib(n){
if(n<2) return n;
return fib(n-1) + fib(n-2);
};
و هذا هو الكود الخاص بالوظيفه memFib اختصارا ل memoized fibonacci بعد تطبيق ال memoization عليها ، الشرح يلى الكود :
//the memoized version of fibonacci
function memFib(n){
if(!memFib.cache){
memFib.cache = [0,1];
}
var result = memFib.cache[n];
if(typeof result == "undefined"){
result = memFib(n-1) + memFib(n-2);
memFib.cache[n] = result;
}
return result;
};
السطر الثالث فى الكود السابق يقوم بفحص هل تم تعريف ال cache من قبل ك static property للوظيفة memFib ، إذا لم يكن تم تعريفه سيتم إعطاءه مصفوفة تحتوى على 0 و 1 و هى ال fibonacci number للرقم 0 و 1 ، اى ان ال key هو الرقم و ال value هو رقم fibonacci لهذ الرقم ، السطر السادس يتم إستخلاص رقم ال fibonacci للرقم n من ال cache ، إذا كان هناك رقم fibonacci سيتم إرجاعه من السطر 11 ، ان لم يكن هناك رقم fibonacci للرقم n سيتم حسابه فى السطر الثامن و سيتم تخزينه فى السطر التاسع فى ال cache لإستخدامه لاحقا ثم إرجاعه فى السطر 11.
و النتيجة لا توصف
الكود التالى يوضح كم مرة الوظيفة memFib و الوظيفة fib نادت نفسها لحساب ال fibonacci number لنفس الرقم بإستخدام الوظيفة howMany من الموضوع السابق :
howMany(fib, 10); // 176 calls howMany(memFib, 10); // 18 calls howMany(memFib, 10); // 1 call - result from [cache] howMany(fib, 20); // 21,891 calls howMany(memFib, 20); // 21 calls - [cache] used howMany(fib, 15); // 1973 calls howMany(memFib, 15); // 1 call - result from [cache] howMany(fib, 9); // 109 calls howMany(memFib, 9); // 1 call - result from [cache] howMany(fib, 25); // 242785 calls howMany(memFib, 25); // 11 calls [cache] used
هههههههههه تم تقليل 242,785 إستدعاء إلى 11 إستدعاء فقط
و إذا إستدعينا memFib مرة أخرى ستنادى نفسها مرة واحدة فقط لأن الناتج موجود فى ال cache .
السلام عليكم و رحمة الله تعالى و بركاته
لنفرض أنك تقوم بكتابة recursive function تقوم بإستدعاء نفسها عدد معين من المرات بناءا على العبارات التى تستقبلها لحساب الناتج ، مثلا يقال ان الوظيفه Fibonacci لكى تحسب ال Fibonacci number للعد 20 فإنها تنادى نفسها 21 الف و 890 مرة
خخخخخ ، و يقال ان الوظيفة Factorial لكى تحسب ال factorial number للعدد 20 فإنها تنادى نفسها 20 مرة ، بما ان هذه الوظائف Idempotent اى ان الناتج لا يتغير مادام العبارات ثابتة يمكننا اخضاعها ل optimization pattern مثل ال Memoization لتقليل هذا العدد الهائل من المرات التى تنادى بها نفسها ، هذا موضوع المقال القادم إن شاء الله ، لكن هذا الموضوع عن معرفة العدد الذى تنادى به ال recursive function نفسها ، هذه المعلومة تهمنى للغاية لأنى أقوم بكتابة بعض ال Benchmarks لوظائف recursive ، يمكنك معرفة ذلك من خلال profiler او debugger فى المتصفح او IDE مثل Aptana Studio على سبيل المثال ، لكنى بعد العديد من المحاولات كتبت وظيفه howMany تقوم بحساب عدد المرات التى تنادى الوظيفة ال recursive نفسها بناءا على طريقة عمل Alias Chaining فى لغة البرمجة Ruby تم تعديل الكود ، الكود التالى يوضح الوظيفه Fibonacci :
function fibonacci(n){
if(n<2) return n;
return fibonacci(n-1) + fibonacci(n-2);
};
fibonacci(10); //55
fibonacci(13); //233
و عن طريق الوظيفة howMany يمكننا حساب عدد المرات التى تنادى فيها الوظيفة fibonnaci نفسها لتحسب ال fibonacci number للعدد 10 و 13 ، الوظيفة howMany تقبل العبارة الاولى لها recursive function و باقى العبارت هى العبارت التى ستمرر لهذه ال recursive function كما يلى :
howMany(fibonacci, 10); //call itself 176 times howMany(fibonacci, 13); //call itself 752 times howMany(fibonacci, 20); //call itself 21,890 times
كما ترى تمكننا من حساب كم مرة تنادى الوظيفة fibonacci نفسها ، و يمكننا تطبيق المثال السابق على اى وظيفة اخرى .
مميزات howMany :
تقوم بحساب عدد المرات التى تنادى ال recursive function نفسها دون الحاجة إلى تشغيل ال debugger او ال profiler فى كل مرة للحاجة لمعرفة ذلك ، و عليه يمكن دمجها فى test suits المكتوب بجافاسكربت .
عيوب howMany :
لا يمكنها حساب عدد المرات التى تنادى فيها ال recursive function نفسها إذا كانت anonymous او كانت ناتجة عن closure .
الكود الخاص ب howMany :
function howMany(fn){
howMany.__times__ = 0;
var args = Array.slice(arguments, 1),
fnStr = fn.toString();
if(fnStr.indexOf("++howMany.__times__;") < 0){
eval(fn.name + " = " + fnStr.replace(/\{/, "{++howMany.__times__;"));
}
fn.apply(null, args);
return howMany.__times__;
};
فى الموضوع القادم سأستخدم howMany لمقارنة المرات التى نادت ال recursive function نفسها قبل و بعد تطبيق ال optimization patterns عليها .
السلام عليكم و رحمة الله تعالى و بركاته

أعطى دوجلاس كروكفور منذ يومين محاضرة بعنوان The Metamorphosis of Ajax ضمن فعاليات سلسلة Crockford on JavaScript ، تم اليوم رفع المحاضرة فيديو يمكنك تحميل نسخة عالية الجودة 720 ميجا بايت من هنا ، المحاضرات السابقة ستجدها فى الموضوعات السابقة و فى موقع السلسلة .
السلام عليكم و رحمة الله تعالى و بركاته

أعطى دوجلاس كروكفورد المحاضرة الثالثة بعنوان Function the ultimate ضمن فعاليات سلسلة Crockford on JavaScript و تحدث خلالها عن ال Function فى الجافاسكربت و ال Prototypal inheritance و ال Semi classical inheritance و ال Functional programming و مواضيع كثيرة أخرى متعلقة ب JavaScript Function . يمكنك تحميل فيديو المحاضرة عالى الجودة من هنا ، او يمكنك تحميل فيديو متوسط الجودة من هنا ، او مشاهدتها اونلاين بصيغة عالية الجودة من هنا ، و اخيرا صور من الحدث .