اذهب إلى المحتوى

لوحة المتصدرين

  1. Wael Aljamal

    Wael Aljamal

    الأعضاء


    • نقاط

      13

    • المساهمات

      6975


  2. سامح أشرف

    سامح أشرف

    الأعضاء


    • نقاط

      6

    • المساهمات

      2934


  3. Ahmed Sharshar

    Ahmed Sharshar

    الأعضاء


    • نقاط

      3

    • المساهمات

      348


  4. Flutter Dev

    Flutter Dev

    الأعضاء


    • نقاط

      2

    • المساهمات

      787


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 12/31/21 في كل الموقع

  1. IEEE (معهد مهندسي الكهرباء والإلكترونيات Institute of Electrical and Electronics Engineers -آي تربل إي-) هي أكبر مجتمع مهني في العالم وتضم مهندسين ومهنيين من خلفيات مختلفة مع الكثير من المتطوعين الخبراء في جميع أنحاء العالم. هدف المعهد هو تحقيق التقدم التعليميّ والتقنيّ في مجال الهندسة الكهربائية والإلكترونيّة والحاسبات وما في حكمها. تعتبر الجمعية من أشهر واضعي المعايير الصناعية عالميا حيث تشمل مجالات عديدة كالطاقة الكهربائية والأجهزة الطبية والإلكترونيات والاتصالات وتكنلوجيا المعلومات ويقوم فرع متخصص من الجمعية بعملية تحديد وتطوير المعايير الصناعية في المجالات المذكورة، ومن أشهر المعايير المتخذة مجوعة المعايير IEEE 802 LAN/MAN والتي تتضمن المعيار الشهير آي إي إي إي 802.3 إيثرنت والمعيار آي إي إي إي 802.11 المتعلق بالشبكات الاسلكية. ISO وهي اختصاراً ل (المنظمة الدولية للمعايير International Organization for Standardization) هي منظمة تعمل على وضع المعايير، وهي تصرح عن معايير تجارية وصناعية عالمية. إذاً يمكنك أن تلاحظ أن ISO هي أكثر عمومية أما IEEE فهي متخصصة في جوانب محددة. ACM حسب معرفتي فهي لاتركز على وضع معايير كما IEEE و ISO حيث يركز أكثر على الحوسبة والمجالات المتعلقة بال CS مثل تحليلات البيانات والبرمجة وتعدين البيانات والويب والبرمجيات.وهي اختصار ل Association for Computing Machinery وهي أول رابطة علمية وتعليمية للحوسبة في العالم. وتقوم الرابطة بالعديد من النشاطات التعليمية المتعلقة بالحاسوب مع العديد من الجامعات، كما تقوم بتنظيم المؤتمرات والمسابقات وإصدار مجلات ومنشورات متعلقة بالحاسوب. وهي بذلك تقوم بدور مشابه إلى حد ما لما تقوم به منظمة جمعية مهندسي الكهرباء والإلكترونيات IEEE.
    2 نقاط
  2. عادة تطبيق المهام هو امر بسيط، حيث تكوتدت القائمة عبارة عن مصفوفة أغراض وكل غرض يمثل مهمة معينة ،و المهمة لها رقم و عنوان و تفاصيل و تاريخ إنجاز و أي بيانات تريدها.. المطلوب منك لبناء تطبيق ملاحظات جافاسكربت في المتصفح هو خوارزمية البحث الخطي Linear Search تفيدك في تعديل و حذف مهكة ضمن المصفوقة بعد البحث عن المهمة التي يريد التعديل عليها المستخدم، يمكنك البدء بهذه الخوارزمية و تدعى أيضا Brute Force.
    2 نقاط
  3. ارغب في تعلم صنع برامج محاسبية فمن اين أبدأ ؟ ليست لدي خلفيه عن اللغه المناسبة لكي اختصر الجهد والوقت
    1 نقطة
  4. عايزه قيمه الinside تتغير ب false بعد ما ادخل الexitdate
    1 نقطة
  5. يمكنك تنفيذ المطلوب عبر تغيير قيمة الinside ل false للكائن res كما بالشكل التالي res.inside = false ولكن ستقابلك مشكلة وهي أن الدالة order_by تقوم بإرجاع Query لا تقوم بإرجاع نتيجة الحل أن نقوم بإرجاع نتيجة عبر مناداة الدالة first ليكون الشفرة البرمجية خاصتك على الهيئة التالية res = vehicles_schedule.query.filter_by(vehicle_id = result.vid).order_by('entrydate').first() ومن ثم سيتم تغيير القيمة عند مناداة الsession.commit() بالتوفيق
    1 نقطة
  6. لدي نطاق مستعمل على استضافة الان وسوف ينتهي قريب حيث انه تم تحديد موعد الانتهاء وهو بعد استكمال سنة حيث انني قمت بحجزه لمدة سنه مسابقا استفساري بعد انتهاء مدته وستكمل سنه كامله هل يصبح النطاق متاح من جديد للحجز مباشره بعد موعد انتهاء في حالة عدم تجديد الاشتراك؟ السبب انني قمت بحجز استضافة جديده على نفس الشركة وقد حصلت على نطاق مجاني يأتي لدى الاستضافة ولكني لا استطيع حجز النطاق الان بسبب توفره في استضافتي السابقة
    1 نقطة
  7. شكرا لك اخي الكريم فعلا المشكله كانت بسبب تكرر الجدول في الاستعلام قمت بفصل الجداول الى جدولين على الأقل في كل استعلام واصبح الامر يعمل بشكل ممتاز كل الشكر لك اخي الكريم واعتذر على تاخر ردي
    1 نقطة
  8. أحاول إضافة صنف CSS Class إلى أحد الحقول في wtform لكي أتحكم في شكله من خلال CSS لذلك قمت بكتابة هذا الكود: في ملف العرض view: form.test_field = forms.ClassedTextField('Test Name') في ملف jinja: {{ form.test_field }} ويتم إنتاج الحقل الحقل في النهاية بهذا الشكل: <input id="test_field" name="test_field" type="text" value=""> لكن المشكلة أني لا أعلم كيف يمكن إضافة صنف CSS إلى الحقل السابق بإستخدام wtform؟
    1 نقطة
  9. ما الفرق بين معايير (standard) لكل من ieee و ecm و iso
    1 نقطة
  10. يوجد عدد من الخوارزميات التي يمكنك تطبيقها على تطبيق كهذا ويتمحورون غالبًا في نطاق الترتيب والبحث يمكنك توفير خاصية أن يتم ترتيب القائمة حسب الإسم أو التاريخ ويمكنك مرة تجربة الترتيب بخوارزمية الbubble sort ومرة أخرى بخوارزمية الinsertion sort يمكنك توفير خاصية البحث بالإسم أو بالتاريخ وتجربة عدة خوارزمية للبحث مثلًا لو كانت القائمة مرتبة يمكنك إستخدام خوارزمية ال binary search tree إن لم تكن مرتبة يمكنك إستخدام خوارزمية الlinear search
    1 نقطة
  11. تستطيع أن تقوم بتمرير الرسائل بإستخدام معاملات عنوان URL (تسمى URL parameter) بالشكل التالي: from flask import session, url_for def foo(): messages = json.dumps({"title":"hello world"}) # تحويل الكائن إلى نص return redirect(url_for('hello', messages=messages)) @app.route('/hello') def hello(): messages = request.args['messages'] # لإستعادة الرسائل من الدالة url_for() return render_template("hello.html", messages=json.loads(messages)) أو يمكنك أن تستعمل الجلسة session لتخزين قيمة message في cookie ثم إستخراج قيمة message من داخل هذه الـ cookie في الدالة hello بالشكل التالي: from flask import session, url_for def foo(): messages = json.dumps({"title":"hello world"}) # تحويل الكائن إلى نص session['messages'] = messages # تخزينه في الـ session return redirect(url_for('hello')) @app.route('/hello') def hello(): messages = session['messages'] # لإستعادة الرسائل من الـ session return render_template("hello.html", messages=json.loads(messages))
    1 نقطة
  12. يتوجب وضع المسار المطلق absolute path للملف المراد التعامل معه، يمكنك نسخ كامل مسار الملف input file من خصائصه أو من مستعرض الملفات. و نضع المسار الكامل مع اسم الملف في دالة open مكان استخدامك لاسم الملف
    1 نقطة
  13. إن Java Swing هي المكتبة الرسومية الأقدم في مجال تصميم واجهات البرامج في لغة جافا، وتملك خزينة من المكونات أكثر أي المكتبة البرمجية الخاصة بها أكبر وتحوي الكثير من العناصر و UI components، بينما JavaFX هي الأحدث و تحوي مكونات أيضا و تدعم MVC وهي أقرب ل internet application وتفيد في المحمولية Portapility أي قابلة للعمل على أنظمة تشغيل أكثر و بتوافق أفضل، كما تدعم CSS و animation وأكثر حداثة. JavaFX هي الأفضل. يوجد عدة مقالات تعلم استخدام JavaFX ضمن الأكاديمية:
    1 نقطة
  14. التعليمة البرمجية DELETE تنفذ استعلام حذف على الجدول ويمكن تمرير شرط كما في الاستعلام في مثالك حيث يحذف المستخدم رقم 1، ويمكن من خلالها حذف سجل أو أكثر مرة واحدة حسب السجلات التي تحقق الشرط. مثل حذف مجموعة المستخدمين الذين رقمهم أصغر من 10: WHERE id < 10; أما تعليمة DROP تقوم بهدم الجدول وحذف كل محتوياته دفعة واحدة، و الشرط IF EXISTS موجود لتجنب حدوث خطأ وتوقف البرنامج في حال كان الجدول محذوف من قبل. موسوعة حسوب: الحذف من جدول SQL
    1 نقطة
  15. يمكنك أن تقوم بعرض أي رقم float بخانتين فقط بعد العلامة العشرية من خلال إستعمال الدالة format، بالشكل التالي: {{'%0.2f'| format(result|float)}}% أو من خلال إستخدام علامة % كما في الكود التالي: {{'%0.2f' % result|float}}% أيضًا تستطيع إستعمال المُرشح round لتقريب الرقم بالشكل التالي: {{ result|round }} وتستطيع تحديد كيف ستتم عملية التقريب من خلال تمرير معاملات إلى المرشح round بالشكل التالي: {{ result|round(1, 'common', ) }} المعامل الأول هو مقدار الدقة precision وقيمته الإفتراضية هي 0، بينما المعامل الثاني هو كيف ستتم عملية التقريب "ceil" (التقريب إلى الرقم الأعلى) أم "floor" (التقريب إلى الرقم الأقل) أم "common" (التقريب الرياضي العادي).
    1 نقطة
  16. تستطيع إستخدام التابع query.one والذي يقوم بإرجاع نتيجة واحدة فقط، وفي حالة وجود أكثر من نتيجة سوف يقوم برفع استثناء MultipleResultsFound أما إذا لم يتم العثور على أي نتائج فسوف يقوم برفع استثناء NoResultFound، ويمكن تطبيق هذه الفكرة من خلال جملة Try .. except، على النحو التالي: from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.orm.exc import MultipleResultsFound try: user = session.query(User).one() return jsonify(result) except MultipleResultsFound, e: return "more than one" except NoResultFound, e: return "no results found" بهذا الشكل يمكنك تنفيذ ما تريد عندما يوجد نتيجة واحدة فقط أو يوجد عدد أكبر من النتائج أو لا يوجد نتائج على الإطلاق.
    1 نقطة
  17. يوفر فلاسك Flask الخاصية endpoint في الكائن request وهي مسئولة عن حفظ اسم الدالة التي يتم تنفيذها عند زيارة المسار، انظر الكود التالي: from flask import Flask, request app = Flask(__name__) @app.route("/") def foo(): return request.endpoint # foo app.run(debug=True) عند زيارة المسار / سوف يتم إرجاع اسم الدالة "foo". يمكنك أيضًا أن تقوم بإستخدام المكتبة inspect للحصول على اسم الدالة الحالية، على النحو التالي: import inspect @app.route("/") def foo2(): return inspect.currentframe().f_code.co_name عند زيارة المسار / سوف يتم إرجاع اسم الدالة "foo2".
    1 نقطة
  18. يمكنك استخدام خيار آخر هو استخدام متغير نقطة النهاية كما في الطريقة التالية @app.route("/api/v1/generate_data", methods=['POST'], endpoint='v1') @app.route("/api/v2/generate_data", methods=['POST'], endpoint='v2') def generate_data(): version = request.endpoint return version إذا كنت تريد سلوكا مختلفا لكل مسار ، فيمكنك القيام بإنشاء دالتين مختلفتين لفعل ذلك كما هو واضح في المثال التالي @app.route("/show-users/") @requires_auth def top(): ... @app.route("/users/") @requires_auth def anti_top(): ...
    1 نقطة
  19. إستخدم التابع Query.first للحصول على صف واحد فقط وليس مجموعة من الصفوف بالشكل التالي: users = session.query(user.name).filter(and_(user.email == email, user.password == password_hash)).one() وتستطيع أيضًا أن تستعمل التابع Query.one_or_none والذي يقوم بإرجاع نتيجة واحدة فقط أو None في حالة لم يتم العثور على نتيجة مطابقة في قاعدة البيانات: users = session.query(user.name).filter(and_(user.email == email, user.password == password_hash)).one_or_none()
    1 نقطة
  20. يوفر فلاسك Flask إمكانية الوصول إلى المسار الحالي من خلال إستخدام الكائن request، حيث يحتوي على الخاصية path التي تحمل المسار الحالي: from flask import Flask, request @app.route("/users/") @app.route("/show-users/") def show_users(): return request.path في الكود السابق سوف يتم عرض المسار المستخدم للوصول إلى الدالة show_users أيضًا يمكنك أن تستعمل url_rule بطريقة مشابهة، على النحو التالي: from flask import Flask, request @app.route("/users/") @app.route("/show-users/") def show_users(): return str(request.url_rule) وسوف يؤدي هذا الكود نفس الغرض.
    1 نقطة
  21. لاحظ أن طريقة كتابة الاستعلام لديك فيها خطأ، حيث أن الاستعلام يقوم بدمج نتائج جدولين أو أكثر (جداء الأسطر) مما يؤدي لعمل جدول يحوي لكل سطر فيه ناتج تكرار كل سطر من أول جدول مع جميع أسطر الجدول الثاني (حجم بيانات ضخم و استعلام معقد.. string com = "select * from TCity , TColors "; ^^^^^^^^^^^^^^^^ cartisan product الحل لديك هو عمل استعلام منفصل لكل جدول و نشر بيانات الاستعلام في القائمة المناسبة. يمكن للتبسيط: اكتب stored procedure يأخذ اسم الجدول كوسيط ويجلب بيناته.. CREATE PROCEDURE getTableData @TableName Varchar(30) AS BEGIN DECLARE @query set @query = 'SELECT * FROM '+ @TableName EXEC @query END --**************************************************** CREATE PROCEDURE getTableData @TableName varchar(30) AS SELECT * FROM @TableName --**************************************************** IF NOT EXISTS(SELECT * FROM sys.tables WHERE name = @tablename) RETURN DECLARE @sql NVARCHAR(30) SET @sql = 'SELECT * FROM ' + QUOTENAME(@tablename) EXECUTE(@sql) شرح المشكلة: اقرأ فقرة الضم المتقاطع Cross Join من المقالة
    1 نقطة
  22. لحل السؤال علينا فهم الخوارزميات العودية حيث يقوم التابع function باستدعاء نفسه ولكن للمرحلة التالية من حل المشكلة، ولكل استدعاء حالة مميزة عن باقي الحالات، في مسألتنا يجب تجريب وضع جميع المعاملات الرياضية مكان كل اشارة استفهام ثم الانتقال للإشارة الاستفهام التالية و تجريب جميع المعاملات.. لذلك سيكون لدينا دالة تقبل مصفوفة فيها الرموز ورقم الخطوة وفيها حلقة تجرب استبدال ؟ بقيمة جميع المعاملات ثم تستدعي الخطوة التالية (إشارة الاستفهام التالية).. عندما نقوم بتبديل جميع الإشارات يبقى مهمة عمل تقييم للتعبير الرياضي، والتأكد هل القيمة هنا تساوي 0 حسب شرط المسألة؟ هنا استخدمت مكتبة math والدالة evaluate للتحقق. يوجد 180 حل مختلف للمسألة const math = require("./math.js"); // مكتبة خارجية const operands = ["+", "-", "*", "/", "%"]; // مصفوفة المعاملات let sequence = "10 ? 20 ? 15 ? 3 ? 190 ? 10 ? 400"; // السلسة التي تعبر عن المعادلة let maxStep = sequence.split("?").length - 1; // عدد إشارات الاستفهام let numberOfSolutions = 0; // عدد الحلول sequence = sequence.split(" "); // تحويل السلسة لمصفوفة لنتمكن من تعديل القيم // لايمكن تعديل قيم String // لأنها نمط immutable //console.log(maxStep); function solve(seq, step) { // دالة الحل تقبل مصفوفة القيم و الرموز و الوسيط الثاني هو رقم إشارة الاستفهام //console.log(step); if (step === maxStep) { // بعد الوصول لآخر خطوة نحسب التعبير let fin = seq.join(""); // دمج المصفوفة //console.log(fin); if (math.evaluate(fin) === 0) { // نمرر السلسسة للتقييم وفي حال وجود حل numberOfSolutions++; console.log("solution ", numberOfSolutions, ": ", fin); // نطبع الحل } return; } let index = step * 2 + 1; // حساب دليل العنصر الحالي الذي نريد تبديله let nextStep = step + 1; // رقم الخطوة التالية for (let op = 0; op < operands.length; op++) { // تجريب المعاملات seq[index] = operands[op]; // استبدال المعامل مكان إشارة استفهام هذه الخطوة solve(seq, nextStep); // استدعاء الدالة للخطوة التالية } } solve(sequence, 0); // استدعاء أساسي console.log("numberOfSolutions: ", numberOfSolutions); // طباعة عدد الحلول الملفات: math js.rar
    1 نقطة
  23. linearLayoutManager = new LinearLayoutManager(context) { @Override public boolean canScrollVertically() { return false; } }; recyclerview.setLayoutManager(linearLayoutManager); recyclerView.setNestedScrollingEnabled(false); استخدم هذه
    1 نقطة
  24. حاول إضافة التالي في XML android:descendantFocusability="blocksDescendants" ل <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:descendantFocusability="blocksDescendants" android:orientation="vertical"> ويمكن <LinearLayout android:focusable="false" android:focusableInTouchMode="false" android:descendantFocusability="blocksDescendants"> <android.support.v7.widget.RecyclerView ... /> />
    1 نقطة
  25. هل يمكنك مشاركة صورة للمشكلة؟ عندما تريد وضع نص باللغة العربية، اكتب علامات التنصيص " " ثم اكتب النص داخلها، هذا يقلل من الأخطاء
    1 نقطة
  26. هل تعاني من صعوبة في تطبيق مفاهيم البرمجة الكائنية مع لغة JavaScript؟ إذًا أنت في المكان الصحيح، ففي هذا المقال سنبدأ بمطلع لمفاهيم البرمجة الكائنية (أو الشيئية كما قد يُطلق عليها البعض)، ومن ثم مراجعة نموذج جافا سكريبت في الكائنات، وأخيرًا شرح مفاهيم البرمجة الكائنية في جافا سكريبت، لتحصل على إلمام واف والقصة الكاملة. مراجعة في جافاسكريبت JavaScript يُمكن العودة إلى المقال إعادة تقديم JavaScript لمن أساء فهمها هنا في أكاديمية حسوب للحصول على مراجعة لأساسيات لغة جافا سكريبت وأخذ فكرة عن المغيرات وأنواع الدوال وبقية الأساسيات. البرمجة الكائنية Object-oriented programming إن البرمجة الكائنية (OOP) ما هي إلا نمط برمجي يَستخدم التجريد في إنشاء نماذج/نسخ لتجسيد العالم الحقيقي، وتَستخدم البرمجة الكائنية في ذلك أساليب مُتعدّدة من هذا النمط، فهي تستخدم الوحدات module، وتعدديّة الأشكال polymorphism والتغليف encapsulation، وتجدر الإشارة إلى أن معظم لغات البرمجة تدعم مفهوم OOP أمثال اللغات البرمجية: جافا، بايثون، روبي، وطبعًا جافا سكريبت. يُعالج أو لنقل يَتصور مفهوم البرمجة الكائنية OOP البرنامج كتشكيلة من الأشياء/الكائنات المتعاونة/المترابطة بدلًا من يتصوّره كتشكيلة من الدوال (functions) أو كسرد من الأوامر. ففي مفهوم OOP، كل كائن/شيء له القدرة على استقبال الرسائل، ومعالجة البيانات، وإرسال الرسائل إلى باقي الكائنات، ويُمكن اعتبار أنه لكل كائن object كينونة خاصة به ودور/وظيفة مستقلة عن الكائن الآخر. تُعزز البرمجة الكائنية القدرة على صيانة الشيفرة البرمجية والمرونة في التطوير، وأثبتت جدارتها على نطاق واسع في هندسة البرمجيات الكبيرة، ولأن البرمجة الكائنية تُشدد على استخدام الوحدات module، فإن الشيفرة/الكود المكتوب بمفهوم البرمجة الكائنية هو أبسط في التطوير وأسهل في الفهم مستقبلًا (عند التنقيح والتعديل)، وكما يعزز مفهوم البرمجة الكائنية التحليل المباشر للشيفرة، وفهم الحالات الشائكة فهمًا أفضل من باقي الأساليب البرمجية الأخرى. مصطلحات البرمجة الكائنية المجال في البرمجة الكائنية Namespace ما هو إلا عبارة عن حاوي تسمح للمطوّر بتحزيم جميع الوظائف تحت اسم محدد وفريد. الصنف أو الفئة Class في البرمجة الكائنية يعتني الصنف بكل ما يتعلّق بميزات وخصائص الكائن، والصنف ما هو إلا قالب template تعريفي بخاصيات properties وبطُرق/وظائف methods الكائن object. الكائن Object في البرمجة الكائنية الكائن ما هو إلا حالة/أمثولة instance من صنف class. الخاصية property في البرمجة الكائنية ما هي إلا مميزات وخصائص الكائن، كاللون مثلًا. الطريقة أو الوظيفة Method في البرمجة الكائنية تعتني الطريقة أو الوظيفة كما يُسميها البعض بقدرات الكائن، مثل قدرة المشي مثلًا، وهي دور أو وظيفة مرتبطة مع صنف class. المشيد Constructor في البرمجة الكائنية ما هو إلا طريقة method تُستدعى في لحظة استهلال instantiate الكائن، وعادةً ما يكون له نفس اسم الصنف الذي يحتويه. الوراثة Inheritance في البرمجة الكائنية يُمكن للصنف أن يرث مميزات من صنف آخر. التغليف Encapsulation في البرمجة الكائنية طريقة في تحزيم البيانات data والطُرق methods التي تستخدم البيانات. التجريد Abstraction في البرمجة الكائنية يجب على الاقتران الحاصل من: الوراثة والطُرق methods والخاصيات properties لكائن معقد وشائك التمثيل برمجيًا أن يعكس الواقع المراد محاكاته في البرمجة الكائنية. تعددية الأشكال Polymorphism في البرمجة الكائنية تحمل كلمة Poly بحد ذاتها المعنى "متعدد" وتحمل الكلمة morphism المعنى "أشكال، ويُشير المفهوم ككل إلى أن أكثر من صنف قد يُعرّف نفس الطريقة method أو الخاصية property. البرمجة المعتمدة على النموذج الأولي Prototype البرمجة المعتمدة على النموذج الأوّلي (Prototype-based programming) ما هي إلا نموذج من البرمجة الكائنية OOP ولكنها لا تستخدم الأصناف classes، بل تقوم أولًا بإعداد سلوك أي صنف class ما ومن ثم تُعيد استخدامه، ويُطلق البعض على هذا النموذج: البرمجة بلا أصناف classless، أو البرمجة المَبْدَئِية المنحى prototype-oriented، أو البرمجة المعتمدة على الأمثولة instance-based). يعود أصل اللغة المعتمدة على النموذج الأولي إلى لغة Self، والتي طوّرها David Ungar وRandall Smith، ولكن أسلوب البرمجة بدون أصناف class-less توسّع ونال شهرة كبيرة في العقد الأخير، واُعتمد من قبل العديد من اللغات البرمجية أشهرهم جافا سكريبت. البرمجة الكائنية باستخدام جافا سكريبت المجال Namespace في جافا سكريبت المجال هو أشبه بمستوعب/بحاوية (container) تسمح للمطوّر في تحزيم وظائف تحت اسم فريد، أو اسم تطبيق محدد، ففي جافا سكريبت المجال هو مجرد كائن object كأي كائن آخر يحتوي على طُرق methods، وخاصيات properties، وحتى كائنات objects. ملاحظة هامة: من المهم جدًا الانتباه إلى أنه في جافا سكريبت، لا يوجد فرق بين الكائنات العادية والمجالات namespaces، وهذا يختلف عن اللغات الكائنية الأخرى، الأمر الذي قد يُربك المبرمجين المبتدئين في جافا سكريبت. إن إنشاء مجال namespace في جافا سكريبت بسيطٌ للغاية، فمن خلال إنشاء كائن عام/مشترك/شامل global، ستصبح جميع المُتغيّرات variables والطرق methods، والدوال functions خاصياتٍ لهذا الكائن، ويٌقلل استخدام المجالات namespaces أيضًا من احتمالية تضارب الأسماء في التطبيق، منذ أن كل كائن من كائنات التطبيق ما هي إلى خاصيات كائن شامل/عام معرّفة على مستوى التطبيق. سيُنشئ في الخطوة التالية كائنًا عامًا global وبالاسم MYAPP: // global namespace var MYAPP = MYAPP || {}; يُظهر المثال السابق، كيف تم التأكّد أولًا فيما إذا كان MYAPP معرفًا (سواء في نفس الملف أو في آخر)، ففي حال الإيجاب سيُستخدم الكائن العام MYAPP، وفي حال عدم تعريفه مُسبقًا سيُنشئ كائنًا خالٍ وبالاسم MYAPP والذي سيغلّف encapsulate الطرق methods والدوال functions والمتغيرات variables والكائنات objects. كما يُمكن أيضًا إنشاء مجال فرعي sub-namespaces: // sub namespace MYAPP.event = {}; يوضّح المثال التالي الصيغة المستخدمة في إنشاء مجال namespace وإضافة متغيرات ودوال: // Create container called MYAPP.commonMethod for common method and properties MYAPP.commonMethod = { regExForName: "", // define regex for name validation regExForPhone: "", // define regex for phone no validation validateName: function(name){ // Do something with name, you can access regExForName variable // using "this.regExForName" }, validatePhoneNo: function(phoneNo){ // do something with phone number } } // Object together with the method declarations MYAPP.event = { addListener: function(el, type, fn) { // code stuff }, removeListener: function(el, type, fn) { // code stuff }, getEvent: function(e) { // code stuff } // Can add another method and properties } // Syntax for Using addListener method: MYAPP.event.addListener("yourel", "type", callback); الكائنات الأساسية/القياسية المبنية داخل لغة جافا سكريبت Standard built-in objects تتضمن لغة جافا سكريبت العديد من الكائنات في تركيبتها، على سبيل المثال، يوجد كائنات مثل Math، Object، Array، String، ويُظهر المثال التالي كيفيّة استخدام الكائن Math للحصول على رقم عشوائي باستخدام أحد طُرق method هذا الكائن وهي الطريقة ()random. console.log(Math.random()); ملاحظة: يَفترض المثال السابق وجميع الأمثلة التالية في المقال وجود دالة function بالاسم ()console.log معرّفة تعريفًا عامًا (globally)، مع العلم أن هذه الدالة ليست جزء من اللغة نفسها، ولكنها دالة متوفّرة في العديد من متصفحات الإنترنت لأغراض تشخيص الشيفرة البرمجية debugging. يُمكن العودة إلى مرجع لغة جافا سكريبت: الكائنات الأصلية المعيارية للحصول على قائمة بالكائنات المبينة داخل لغة جافا سكريبت نفسها. كل كائن في جافا سكريبت هو حالة/أمثولة instance من الكائن Object ويَرث كافة خاصياته properties وطُرقه methods. الكائنات المخصصة Custom objects في جافا سكريبت الصنف/الفئة The class لغة جافا سكريبت لغة من النوع prototype-based ولا تحتوي على العبارة class كما هو حال باقي لغات البرمجة الكائنية، كما في روبي أو بايثون، ويُربك هذا الأمر المبرمجين المعتادين على اللغات التي تعتمد على هذه العبارة أو المفهوم، وتستخدم جافا سكريبت بدلًا من ذلك الدوال functions لمحاكات مفهوم الأصناف classes، وتعريف صنف هو بسهولة تعريف أي دالّة: var Person = function () {}; الكائن (أمثولة الصنف class instance) يتطلب إنشاء حالة/أمثولة instance جديدة من كائن obj استخدام العبارة new obj، وتعيين النتيجة إلى متغيّر بغرض الوصول إلى فيما بعد. عُرّف في الشيفرة السابقة صنف class بالاسم Person، وفي الشيفرة التالية، سيُنشئ حالتين/أمثولتين instances من هذا الصنف، الأولى بالاسم person1 والثانية بالاسم person2. var person1 = new Person(); var person2 = new Person(); المشيد The constructor يُستدعى المُشيّد constructor في لحظة الاستهلال instantiation (اللحظة التي يُنشئ فيها الكائن)، والمُشيّد ما هو إلا طريقة method من طُرق الصنف class، وفي جافا سكريبت تعمل الدالة على تشييد الكائن، ولذلك لا داعي إلى تعريف طريقة method من أجل عميلة التشييد، وكل إجراء مصرّح في الصنف class يُنفّذ في لحظة الاستهلال instantiation. يُستخدم المُشيّد في تعيين خاصيات properties الكائن، أو في استدعاء طُرق methods معينة لتحضير الكائن للاستخدام، وأما إضافة طُرق صنف وتعريفها يحدث باستخدام صيغة syntax مختلفة سنتطرّق إليها فيما بعد خلال المقال. تُظهر الشيفرة التالية كيف يُسجّل log (يُرسل رسالة نصية إلى طرفية المتصفح console) مُشيّد الصنف Person رسالة نصية حينما يُستهل instantiated. var Person = function () { console.log('instance created'); }; var person1 = new Person(); var person2 = new Person(); الخاصية The property (خاصية الكائن object attribute) الخاصيات properties ما هي إلا متغيرات محتوات في الصنف class، وكل حالة/أمثولة من الكائن تمتلك هذه الخاصيات، وتُعيّن الخاصيات في دالة مُشيّد الصنف بحيثُ تُنشئ مع كل حالة/أمثولة instance. إن الكلمة المفتاحية this، والتي تُشير إلى الكائن الحالي، تسمح للمطوّر بالعمل مع الخاصيات من ضمن الصنف، والوصول (قراءةً وكتابةً) إلى الخاصية property من خارج الصنف يكون من خلال الصيغة InstanceName.Property كما هو الأمر في لغة C++ (سي بلس بلس) وJava والعديد من اللغات الأخرى، ومن داخل الصنف تُستخدم الصيغة this.Property للحصول على قيمة الخاصية أو لتعيين قيمتها. في الشيفرة التالية، عُرّفت الخاصية firstName للصنف Person وفي لحظة الاستهلال instantiation: var Person = function (firstName) { this.firstName = firstName; console.log('Person instantiated'); }; var person1 = new Person('Alice'); var person2 = new Person('Bob'); // Show the firstName properties of the objects console.log('person1 is ' + person1.firstName); // logs "person1 is Alice" console.log('person2 is ' + person2.firstName); // logs "person2 is Bob" الطرق The methods الطرق methods ما هي إلا دوال (وتُعرّف كما تعرّف الدوال functions)، فيما عدا ذلك فهي تُشبه الخاصيات properties، واستدعاء طريقة method مشابه إلى الوصول إلى خاصيّة ما، ولكن مع إضافة () في نهاية اسم الطريقة، وربما مع مُعطيات arguments، ولتعريف طريقة، تُعيّن دالة إلى خاصيّة مُسمّات من خاصيّة الصنف prototype، ويُمكن فيما بعد استدعاء الطريقة على الكائن بنفس الاسم الذي عُيّن للدالة. في الشيفرة التالية، عُرّفت ومن ثم اُستخدِمت الطريقة ()sayHello للصنف Person. var Person = function (firstName) { this.firstName = firstName; }; Person.prototype.sayHello = function() { console.log("Hello, I'm " + this.firstName); }; var person1 = new Person("Alice"); var person2 = new Person("Bob"); // call the Person sayHello method. person1.sayHello(); // logs "Hello, I'm Alice" person2.sayHello(); // logs "Hello, I'm Bob" إن الطُرق methods في جافا سكريبت ما هي إلا دالة كائن عادية مرتبطة مع كائن كخاصية property، وهذا يعني أنه يُمكن استدعاء الطُرق خارج السياق، كما في المثال التالي: var Person = function (firstName) { this.firstName = firstName; }; Person.prototype.sayHello = function() { console.log("Hello, I'm " + this.firstName); }; var person1 = new Person("Alice"); var person2 = new Person("Bob"); var helloFunction = person1.sayHello; // logs "Hello, I'm Alice" person1.sayHello(); // logs "Hello, I'm Bob" person2.sayHello(); // logs "Hello, I'm undefined" (or fails // with a TypeError in strict mode) helloFunction(); // logs true console.log(helloFunction === person1.sayHello); // logs true console.log(helloFunction === Person.prototype.sayHello); // logs "Hello, I'm Alice" helloFunction.call(person1); كما يُظهر المثال السابق، جميع الإحالات المستخدمة في استدعاء الدالة sayHello تُشير إلى نفس الدالة سواءً الاستدعاء الحاصل مع person1 أو Person.prototype أو حتى في المتغيّر helloFunction وقيمة this خلال استدعاء الدالة يعتمد على الكيفية التي تُستدعى فيها، حيث تُشير الكلمة المفتاحية this إلى الكائن الحالي الذي تُستدعى عليه الطريقة method، بمعنى عندما تم استدعاء الطريقة ()sayHello على الكائن person1 فإن this تُشير إلى الكائن person1، وعند استدعاء sayHello على الكائن person2 فإن this تُشير إلى الكائن person2، ولكن إن تم الاستدعاء بطريقة مختلفة، فإن this ستُعيّن تعينًا مختلفًا، فاستدعاء this من المتغيّر (كما في ()helloFunction) سيُعيّن this إلى الكائن العام global (والذي سيكون window في متصفح الإنترنت)، ومنذ أن هذا الكائن (على الأغلب) لا يملك الخاصّيّة firstName، ستكون النتيجة كما هو الحال في المثال السابق “Hello, I’m undefined”، كما يمكن دائمًا تعيين this صراحةً باستخدام Function#call (أو Function#apply) وهو كما كان في نهاية المثال. الوراثة تُستخدم الوراثة في جافا سكريبت في إنشاء صنف class كمثيل مخصص لصنف أو أكثر (تدعم جافا سكريبت وراثة وحيدة فقط single inheritance)، ويُطلق على الصنف المخصص عادةً ابن (child)، ويطلق على الصنف الآخر عادةً الأب (parent)، وفي جافا سكريبت يتمّ ذلك من خلال إسناد حالة/أمثولة من الصنف الأب إلى الصنف الابن، ومن ثم تخصيصه، وفي متصفحات الإنترنت الحديثة يُمكن استخدام Object.create في تحقيق الوراثة inheritance أيضًا. ملاحظة: لا تتفقد جافا سكريبت مُشيّد صنف الابن prototype.constructor (راجع Object.prototype)، وعليه يجب التصريح عن ذلك يدويًا، لمزيد من التفصيل راجع السؤال التالي على Stackoverflow. عُرّف في الشيفرة التالية الصنف Student كصنف ابن للصنف Person، ومن ثم أُعيد تعريف الطريقة ()sayHello وأُضيفت الطريقة ()sayGoodBye علاوة على ذلك. // Define the Person constructor var Person = function(firstName) { this.firstName = firstName; }; // Add a couple of methods to Person.prototype Person.prototype.walk = function(){ console.log("I am walking!"); }; Person.prototype.sayHello = function(){ console.log("Hello, I'm " + this.firstName); }; // Define the Student constructor function Student(firstName, subject) { // Call the parent constructor, making sure (using Function#call) // that "this" is set correctly during the call Person.call(this, firstName); // Initialize our Student-specific properties this.subject = subject; }; // Create a Student.prototype object that inherits from Person.prototype. // Note: A common error here is to use "new Person()" to create the // Student.prototype. That's incorrect for several reasons, not least // that we don't have anything to give Person for the "firstName" // argument. The correct place to call Person is above, where we call // it from Student. Student.prototype = Object.create(Person.prototype); // See note below // Set the "constructor" property to refer to Student Student.prototype.constructor = Student; // Replace the "sayHello" method Student.prototype.sayHello = function(){ console.log("Hello, I'm " + this.firstName + ". I'm studying " + this.subject + "."); }; // Add a "sayGoodBye" method Student.prototype.sayGoodBye = function(){ console.log("Goodbye!"); }; // Example usage: var student1 = new Student("Janet", "Applied Physics"); student1.sayHello(); // "Hello, I'm Janet. I'm studying Applied Physics." student1.walk(); // "I am walking!" student1.sayGoodBye(); // "Goodbye!" // Check that instanceof works correctly console.log(student1 instanceof Person); // true console.log(student1 instanceof Student); // true فيما يخص السطر ;(Student.prototype = Object.create(Person.prototype في الإصدارات القديمة من جافا سكريبت والتي لا تدعم Object.create يمكن إما استخدام بعض الحيل في خداع المتصفحات –هذه الخدع معروفة إما بالاسم polyfill أو shim—أو استخدام دالة تحقق نفس النتيجة كما في المثال التالي: function createObject(proto) { function ctor() { } ctor.prototype = proto; return new ctor(); } // Usage: Student.prototype = createObject(Person.prototype); التأكّد من أن this تُشير إلى الكائن المطلوب بغض النظر عن كيف للكائن أن يُستهل يمكن أن يكون صعبًا، ومع ذلك يوجد صياغة أبسط من شأنها أن تسهّل الأمر. var Person = function(firstName) { if (this instanceof Person) { this.firstName = firstName; } else { return new Person(firstName); } } التغليف Encapsulation ليس بالضرورة أن يعلم الصنف Student كيف تمّ تنفيذ/تعريف الطريقة ()walk للصنف Person لكي يستطيع استخدام تلك الطريقة، ولا يحتاج الصنف Student إلى تعريف تلك الطريقة صراحةً إلا إذا كان المطلوب التعديل عليها، ويُطلق على هذا الإجراء مفهوم التغليف encapsulation، والذي فيه يَحزم كل صنف البيانات والطُرق methods داخل وحدة/كينونة وحيدة. إخفاء المعلومات سمة شائعة في باقي اللغات البرمجية وعادةً ما توجد كخاصيات/كطُرق إما بالاسم private أو protected، وعلى الرغم من أنه يُمكن مماثلة/محاكاة ذات الأمر في جافا سكريبت، إلا أن هذا الأمر ليس مطلبًا من متطلبات البرمجة الكائنية. التجريد Abstraction التجرير ما هو إلا ميكانيكية تسمح للمطوّر في تجسيد جانب من المشكلة التي يُعمل عليها، إما من خلال الوراثة inheritance (التخصيص specialization) أو التركيب composition، وتُحقق جافا سكريبت التخصيص من خلال الوراثة، والتركيب من خلال السماح لحالات/أمثولات الصنف لتكون قيمًا لخاصيات attributes الكائنات الأخرى. الصنف Function في جافا سكريبت يرث من الصنف Object (وهذا يوضّح التخصيص في هذا النموذج) والخاصية Function.prototype ما هي إلا حالة/أمثولة من الصنف Object (وهذا يوضّح جزئية التركيب composition). var foo = function () {}; // logs "foo is a Function: true" console.log('foo is a Function: ' + (foo instanceof Function)); // logs "foo.prototype is an Object: true" console.log('foo.prototype is an Object: ' + (foo.prototype instanceof Object)); تعددية الأشكال Polymorphism كما أن جميع الطُرق methods والخاصيات properties معرّفة ضمن الخاصية prototype، فيُمكن لبقية الأصناف أن تُعرِّف طُرقًا methods بنفس الاسم، وستكون الطُرق في نطاق الصنف الذي عُرفت به، إلا إذا كان الصنفان على علاقة من نوع أب وابن parent-child، بمعنى آخر أحد الصنفان يرث من الآخر خاتمة إن الأساليب التي تم التطرُّق إليها ليست الأساليب الوحيدة التي يمكن استخدامها في تطبيق مفاهيم البرمجة الكائنية في جافا سكريبت، والتي هي مرنة إلى حد كبير في هذا الصدد، ولم تلجئ إلى أي خدع في تطبيق هذه المفاهيم، ولم تقلّد أيضًا الأساليب والنظريات المستخدمة في اللغات الأخرى، وفي جعبة جافا سكريبت العديد من الأساليب الأخرى لتطبيق مفاهيم متقدمة في البرمجة الكائنية التوجّه، ولكن هذه الأساليب المتقدمة هي خارج إطار مقالة تمهيدية، ربما نتطرّق إليها لاحقًا في الأكاديمية. ترجمة وبتصرّف للمقال Introduction to Object-Oriented JavaScript.
    1 نقطة
×
×
  • أضف...