إبراهيم البحيصي

الأعضاء
  • المساهمات

    43
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • Days Won

    5

السُّمعة بالموقع

28 Excellent

المعلومات الشخصية

  • النبذة الشخصية مبرمج, وكاتب تقني, لدي معرفة جيدة في أنظمة قواعد البيانات مثل Oracle و MySql. محب للبايثون.
    "بايثونات" مدونتي وأكتب عليها من فترة لأخرى.
  • الموقع

4 متابعين

  1. إذا كانت وظيفتك هي إنشاء تصميمات ويب عالية الجودة، عليك أن تدرك أنّ مساهمتك في العملية التسويقية مهمة جدًا، لذلك، فإن قضاء بعض الوقت لصقل معرفتك بتعلم مصطلحات التسويق المشهورة سوف يمنحك فهمًا أكثر لعملك من خلال سياق أكبر في التسويق. كميزة إضافية، من الممكن تعلم بعض المصطلحات التي تستطيع استخدامها في نقاشاتك مع المُشغلين والعملاء وإثارة إعجابهم بمعرفتك وتمكنك في هذا المجال. هذه بعض المصطلحات التي تحتاج للبدء بالتعرف عليها: اختبار أ/ب (A/B Testing) هو نسخة المسوق في المنهج العلمي. عندما تكون هناك مشكلة ما في تصميم موقع، بدلًا من إجراء تعديل شامل على التصميم، او تغيير المحتوى والخطوط أو تغيير الألوان بشكل كامل، يعمد المسوقون لاستخدام اختبار أ/ب كأداة لتجريب نُسخ بديلة للموقع وعادةً ما يتم تغيير عنصر واحد فقط. التحليلات (Analytics) يشير مصطلح التحليلات ببساطة الى بيانات كأرقام. معدل فتح البريد الإلكتروني، وعدد زائري مدونة ما، وعدد النقرات المدفوعة، وعدد المشاهدات وغيره من الأرقام، كل ما سبق يُمثّل مجموعة متنوعة من البيانات التي يُمكن استخلاصها من تحليلات عملية التسويق. B2B يُشير مصطلح B2B الى مفهوم "من قطاع أعمال إلى قطاع أعمال" ونقصد به هنا الطرفان المباشران لعملية التسويق، ويُمثل الطرفان قطاعي أعمال مختلفان بحيث يكون جمهور قطاع أعمال ما هو قطاع أعمال أخر. B2C يشير مصطلح B2C الى مفهوم "من قطاع أعمال إلى المستهلك" وفيه يستهدف قطاع أعمال ما جمهورًا من المستهلكين العاديين (ليسوا قطاع أعمال). معدل الارتداد (Bounce Rate) معدل الارتداد هو نسبة الزائرين الذين يغادرون موقعك بمجرد الدخول لصفحة واحدة. هذه الإحصائية يتم متابعتها لتحديد الجزء الذي يفقد فيه الزائر الاهتمام بالموقع. ستجد هنا دليل يُساعدك في تحسين معدل الارتداد لموقعك. هوية العلامة التجارية (Brand Identity) تتضمن هوية قطاع أعمال ما كل شيء يربطه الناس بالعلامة التجارية الخاصة بهذا القطاع. من الممكن أن تتضمن هوية قطاع الأعمال كل من اسم الشركة، شعار الشركة، ألوان العلامة التجارية، نوع خطوط الطباعة، الصور، محتوى صوتي وهكذا. شخصية المشتري (Buyer Persona) ينشئ قطاع الأعمال هوية جمهوره من خلال بناء ما يًسمى بـ "شخصية المشتري" وتُبنى معالم هذه الشخصية باستخدام المعلومات الجغرافية والسكانية أو تاريخ سلوك المستخدمين وغيره من المعلومات، وتمنح هذه الشخصية الجمهور القدرة على تشكيل محتواه، وتحديد جهود التسويق بالطريقة التي يرغبها. دعوة إلى الإجراء (Call-to-Action) كل صفحة في الموقع لابد أن يكون لها هدف واضح لجمهور الأعمال وكل جزء من التسويق لابد أن يكون مضمونًا. دعوة إلى الإجراء يمثل رسالة تقوم بتوجيه الزائر للقيام بالخطوة التالية لإكمال تحقيق الهدف المُراد منه. المحتوى (Content) المحتوى هو كل شيء يحتويه الموقع من نصوص، وصور، ومقاطع فيديو، ونداء إجراء، ومكونات القائمة الجانبية، والحركات والأيقونات ...إلخ. التحويل (Conversion) التحويل هو غاية التسويق وهدفه النهائي، ويتغير شكل التحويل من موقع لأخر، فالتحويل في مواقع العضويات يتحقق باشتراك الزائر في العضوية. في مواقع التجارة الإلكترونية، التحويل هو شراء سلعة أو منتج. للمدونات، التحويل هو الاشتراك في المدونة ومتابعة الخلاصات فيها. الاشتراك (Engagement) يشير مصطلح الاشتراك الى أي تفاعل بين قطاع أعمال ما والمستخدم النهائي لديه. يستخدم المسوقون هذا المصطلح للإشارة عادةً إلى التفاعل الحاصل في المنصات الاجتماعية والذي يحدث بأشكال متعددة مثل الإعجاب، المشاركة والتعليق. محتوى متجدد (Evergreen Content) يكون المحتوى متجددًا عندما لا يتقيد بوقت ما. وبكلمات أخرى، يبقى هذا المحتوى قيمًا وذو علاقة بغض النظر متى يقوم شخص رؤيته. الارتباك والمقاومة (Friction) تحدث حالة الارتباك ومقاومة التحويل في عملية التسويق عند إزعاج المستخدم وإرباكه أثناء محاولته إتمام إجراء معين. التسويق الضمني (Inbound Marketing) يتطلب التسويق الضمني تكتيكات خفية، وغالبًا يركز على التجربة وشرح الخبرة والمعرفة أكثر من محاولة البيع. الاصطياد (Jacking) الاصطياد (مثل الاختطاف) يحدث عند استخدام فكرة رائجة لصالح قطاع أعمال ولغرض خاص. من أمثلة ذلك هو استخدام newsjacking (تصيد الأخبار الشائعة)، و trendjacking (تصيد المواضيع الشائعة), و memejacking (تصيد النهفات والنكات الشائعة). مؤشر الأداء الأساسي (Key Performance Indicator) نعني بهذا المصطلح (يُختصر بـ KPI) قياس درجة النجاح في تحقيق هدف ما. الكلمة المفتاحية (Keyword) الكلمات المفتاحية هي ما يُركز عليه المسوقون في بناء كل جزء من المحتوى المكتوب. الكلمات المفتاحية هي أحد الطرق التي تُستخدم في تهيئة المحتوى ليناسب محركات البحث. صفحة الهبوط (Landing Page) كل صفحة في موقع ما هي صفحة هبوط. بلغة التسويق، وبشكل خاص، تُصمم صفحات الهبوط لتحقيق هدف خاص بالبيع. العميل المحتمل (Lead) يشير مصطلح Lead في لغة التسويق إلى العميل المحتمل. التسويق المؤتمت (Marketing Automation) التسويق المؤتمت هو عملية تشغيل "مهمة تسويقية" وتنظيمها باستخدام برمجية ما. التهيئة للأجهزة المحمولة (Mobile Optimization) التهيئة للأجهزة المحمولة هو المصطلح العام المستخدم عند تصميم موقع وأخذ الهاتف المحمول في الحسبان. التصميم المتجاوب وتقييم سرعة الصفحة هما مثالان للتهيئة للأجهزة المحمولة. تحسين الصفحة – الداخلي (On-page Optimization) يشير هذا المصطلح إلى أي نوع من التحسينات المتعلقة بعملية البحث التي يتم تطبيقها داخل صفحة ويب. يشمل ذلك استخدام التخطيط المتجاوب وتهيئة النص باستخدام البيانات الوصفية. تحسين الصفحة – الخارجي (Off-page Optimization) يشير هذا المصطلح إلى أي نوع من التحسينات المتعلقة بعملية البحث التي يتم تطبيقها خارج الموقع. الشبكات الاجتماعية وفرص الارتباط هما مثالان على ذلك. التسويق التقليدي (Outbound Marketing) هي العملية التقليدية للتسويق وتكتيكاتها محصورة بغرض البيع المباشر. نقطة الألم (Pain Point) كل حل أو منتج أو خدمة الهدف منه هو حل نقطة ألم للزبون. غالبًا يتم تعريفها عند بناء شخصية المشتري. التطويع (Repurposing) التطويع هو استخدام جزء من محتوى وتجديده كشيء اخر، فمثلًا، يقوم المسوقون بأخذ منشور مدونة ومناقشته خلال جلسة فيديو حية. التهيئة لمحركات البحث (Search Engine Optimization) يشير مصطلح التهيئة لمحركات البحث (السيو SEO) الى أي تكتيك تسويقي يهدف إلى تحسين ترتيب الموقع خلال ظهور نتائج البحث. تحسين الصفحة داخليا وخارجيا هما مثالان للسيو. الإثبات الاجتماعي (Social Proof) يشير الإثبات الاجتماعي إلى اعتماد المستهلك على شهادة الغير من المستخدمين لتحديد نظرته وموقفه تجاه علامة تجارية ما. الشهادات، مراجعات المنتج، التقييمات وصور منتجات الشركة المُصورة من قبل المستخدمين هي أمثلة على الإثبات الاجتماعي. القائد المُفكر (Thought Leader) يُنظر للقائد المُفكر كشخص مؤثر وخبير في مجال مُعين. من منظور تسويقي، يُشير المسوقون للمحتوى التسويقي الداخلي كمحتوى قائد مُفكر. تجربة المستخدم (User Experience) في التسويق، يُستخدم مصطلح تجربة المستخدم (UX) للإشارة غالبًا الى خبرة المستخدم في استخدام شيء ما. يوجد طريقة في تصميم الويب تُسمى تصميم UX والتي تُركز بشكل كبير على بناء كل إنش في الموقع بناءً على إعدادات المستخدمين، سلوكهم وأهدافهم. ترجمة -وبتصرّف- للمقال The Marketing Terms You Need to Know as a Web Designer لصاحبه Brenda Stokes Barron
  2. صُممت صفحة الهبوط هذه كي تتناسب مع الإجراء الذي قاموا به للتو، لذا فإن من الضروري أن تكون دعوة الإجراء (Call to Action) واضحة ومباشرة في صفحات الهبوط المؤثرة. استخدام الإعلانات لتوجيه العملاء لصفحات الهبوط الجذابة هي طريقة رائعة لزيادة الوصول لعلامتك التجارية. بما أن شركة جوجل بدأت بإعطاء أفضلية في التصنيف للمواقع التي تتضمن محتوى فيديو، أصبح استخدام الفيديو طريقة ممتازة لتسريع ولفت الانتباه لعلامتك التجارية. يتميز محتوى الفيديو بالجاذبية لعدة أسباب، لذا فإن الاستفادة من قوة هذا المحتوى في صفحات الهبوط لديك هو أمر حتمي وسيساعدك في الحصول على انطباع عظيم من المرة الأولى من قبل عملائك المحتملين. قوة محتوى الفيديو صفحات الهبوط التي تحتوي على الفيديو هو أحد الاتجاهات القوية في مجال التسويق بالمحتوى. بينما أغلب صفحات الهبوط صُممت بهدف تشجيع العميل على اتخاذ اجراء مُعين مثل تنزيل كتاب الكتروني او الانضمام لقائمة بريدية، فإن محتوى الفيديو يُدخل البهجة والسرور ويسلي العملاء المحتملين. تتميز صفحات الهبوط التي تتضمن محتوى فيديو بقصرها، سهولة استيعابها، وجاذبيتها للمستخدم العصري. ليس كل مستخدم يريد أو لديه الوقت لقراءة محتوى نصي أو تصفح معرض صور، ولكن محتوى الفيديو من الممكن مشاهدته أو الاستماع له بينما يقوم المستخدم بأعمال أخرى، لذلك فمن الأسهل نوعًا ما أن يتم تشجيع العملاء على رؤية محتوى فيديو على أن يقوموا بمشاهدة أشكال أخرى من المحتوى. صفحات الهبوط التي تتضمن محتوى فيديو تستطيع أن ترفع نسبة التحويلات (conversions) إلى 80% وأغلب زوار المواقع يمكثون أطول في الصفحات التي تحتوي على فيديو بنسبة 88% من الصفحات الأخرى. ملاحظة: التحويلات (conversions) هي عملية تحول المستخدم أو الزائر العادي لصفحتك إلى عميل يقوم بشراء خدماتك. محتوى الفيديو فعال خصيصًا لمواقع التجارة الإلكترونية حيث يثق المستخدمون بنسبة 52% أكثر في عمليات شرائهم من المواقع التي تتضمن محتوى فيديو. أضف إلى ذلك أن المستخدمين الذين يشاهدون فيديو على المتاجر الإلكترونية يمكثون في هذه المواقع دقيقتين أكثر، مع احتمالية زائدة للشراء بنسبة 64%. صفحات الهبوط التي تتضمن فيديو مقابل صفحات الهبوط التقليدية يتغير التسويق الرقمي باستمرار ويبقى مجالًا تنافسيًا بشكل كبير. يُغمر المستهلكون بالإعلانات والمحتوى المدعوم والعديد من الأشكال الأخرى للتسويق والتي ببساطة لا تكترث لأي شيء يُعيد تشكيل الإعلان من جديد. يقوم خبراء التسويق الحديث بمهمة خلق انطباعات جديرة بالبقاء في ذاكرة المستهلكين بهدف التميز عن المنافسين الآخرين وبهدف عرض قيمة حقيقة يهتم بها من يشاهدها. تبقى صفحات الهبوط العادية طريقة ممتازة لعرض المحتوى الذي يهتم به المتصفحون، وأنهم في المكان الصحيح الذي يناسب حاجاتهم، وأن هذا المكان هو الذي يتعرفون فيه أكثر عنك وعن علامتك التجارية. بعد الضغط على إعلانك التجاري الموضوع في المكان الصحيح، يتم توجيه المتصفحين الى صفحة الهبوط التي سوف يستفيدون فيها من عرضك مثلًا، أو يحصلون فيه على هدية مجانية او للتعرف عنك أكثر. إن من الضروري أن تكون القيمة والأهمية أمران واضحان للمستخدم وإلا فإنه ببساطة سوف يعتقد أنك ضيعت وقته. يجب أن يكون هناك حافز واضح لجعل المستخدم يضغط على الرابط، ويجب أن تكون النتيجة كما يتوقعه المستخدم، وإذا لم يحدث ذلك، فسوف تتضرر قيمتك لديهم وسيتضرر بالإضافة لذلك معدل التحويل الخاص بك. وبمجرد أن يعتبر أحد المستخدمين أن علامة تجارية معينة أصبحت غير جديرة بالثقة أو ليست من ضمن اهتماماته، فإنه من الصعوبة الكبيرة إعادة الثقة المفقودة. تقوم شركة جوجل بإعطاء أولوية للمواقع التي تحتوي على محتوى فيديو وهذا أحد الفوائد الكبيرة لصفحات الهبوط المرئية. إذا تم تهيئة موقعك لمحركات البحث فإن ترتيب موقعك والوصول إليه سيتحسنان بفضل صفحات الهبوط التي تتضمن فيديو وهذا الوصول الإضافي قيمٌ جدًا لقوة التنافس الحاصل بين المواقع في الحصول على ترتيب أعلى. الهاتف أولًا أدرك العديد من المسوقين مدى القدرة المذهلة لتطوير المحتوى تحت شعار "المحمول أولًا". يستمر معدل مشاهدة المحتوى الخاص بالمحمول في الزيادة ومنطلقًا كالصاروخ كلما زاد عدد مستخدمي الهواتف الذكية وكلما زاد معدلهم في تصفح الانترنت، التسوق ودفع الفواتير. كلما تقدمت تقنية الهاتف الذكي يصبح من السهل شراء أجهزة محمولة ذات عتاد قادر على عرض فيويو عالي الجودة، وتبعًا لذلك، فإن محتوى الفيديو يزداد استهلاكه أكثر فأكثر مع مرور الوقت. أحد الركائز الأخرى للتسويق العصري هو التصميم المتجاوب (Responsive Design). الفضل يعود للوفرة في الخيارات المتاحة للمستهلكين والموجودة في الأجهزة القادرة على الاتصال بالإنترنت، حيث أصبح من المهم أكثر مما مضى أن تُصمم موقعك ومحتواك ليكون مناسبًا للعرض على أغلب الأجهزة المختلفة. فمثلًا من المهم أن تفكر بخيار التنقل بالإبهام (Thumb Navigation) عند تصميم مواقعك بما أن العديد من مستخدمي الهاتف لن يقوموا باستخدام الفأرة للتنقل في المحتوى الخاص بك. إن تهيئة المحتوى ليناسب أجهزة الهواتف الذكية هو أمر ضروري في التسويق الرقمي الحديث، ويدرك محترفو التسويق قيمة الاستثمار في المحتوى المرئي المعروض في مواقع مُهيئة ومُصممة جيدًا. تفتح الهواتف الباب واسعًا لإجراء حملات تسويقية متقدمة ومخصصة، فمثلاً، يستطيع المسوقون تفصيل المحتوى بناءً على الموقع الجغرافي للمستخدم وذلك بهدف تقديم محتوى ذو علاقة أكثر فأكثر. قد يكون هذا الأمر خيارًا غير واقعي لكل جزء في محتوى الفيديو، ولكن يبقى مهمًا تذكر أن المحتوى المُوجه بناءً على المكان الجغرافي له أثاره العميقة على معدل التحويل لديك. نصائح لصفحات الهبوط التي تتضمن فيديو يوجد عدد كبير من الأدوات المتاحة لتطوير محتوى الفيديو بتكاليف بسيطة أو تكاد تنعدم. من الناحية العملية، تستطيع أي مؤسسة أو جهة عمل إنتاج محتوى فيديو عالي الجودة، لذا من المهم الاستفادة من هذه الفرصة بأسرع ما يمكن. قيمة المحتوى المرئي أصبحت معروفة منذ سنوات، وإذا لم تستثمر هذا الأمر لصالح علامتك التجارية، فإن منافسيك بالتأكيد قاموا بذلك لصالحهم. النصائح التالية تُساعدك في بناء صفحات هبوط ذات محتوى فيديو عالي الجودة: ابدأ الآن. إذا لم تدرك بعد أهمية محتوى الفيديو فإن منافسيك أدركوا ذلك قبلك. من المهم الاستثمار في محتوى الفيديو في صفحات الهبوط بأسرع وقت ممكن. الفيديو الخاص بك سيتحسن مع زيادة الفحص والخبرة ومع مرور الوقت، لذا لا ترتبك أو تتراجع إذا لم تكن التجربة الأولى لك مثالية كما تتوقعها. لا تجعل التكلفة تؤثر عليك. إن تكلفة انتاج محتوى الفيديو أرخص مما يدركه أغلب المسوقين. حتى مع امتلاكك خبرة قليلة أو منعدمة في إنتاج الفيديو، لا ينبغي عليك إبهار جمهورك من البداية، يكفي عليك أن تقدم لهم شيئًا ممتعًا وذو قيمة. المحتوى المرئي البسيط مثل الحديث عن قصص نجاح العملاء لديك، عرض نماذج من المنتجات، أخبار الشركة، كل ما سبق هو طريقة عظيمة للبدء في تقديم محتوى فيديو لعملائك. اعرف جمهورك. تُعتبر بيانات العملاء ذات الجودة العالية أحد أهم وأقوى الأدوات في ترسانة المسوق. إذا كان لديك فكرة واضحة جدًا عن العملاء الذين تريد جذبهم إليك، قم ببناء محتوى مرئي يستهدف حاجاتهم ورغباتهم، وقم بالإجابة فيه عن أسئلتهم المتوقعة التي يسألونها عن علامتك التجارية. اعرف كيف تُهيئ محتوى الفيديو. محتوى الفيديو جذاب، ولكنه قد يكون مزعجًا للبعض. فمثلا، خيار التشغيل التلقائي قد يُفجر الصوت الخاص بالفيديو لدى العميل. تأكد أن المستخدم يستطيع وقف وتشغيل الفيديو متى ما أراد ذلك، بالإضافة لقدرته على توسيع المحتوى ليشمل الشاشة كلها وكتم الصوت إذا أراد. من الممكن أيضًا استخدام خاصية التنصيص المغلق (Closed Captioning) خلال المحتوى المرئي بهدف الوصول إلى شريحة أكبر من الجمهور. اجعل محتوى الفيديو ذو علاقة وذو قيمة. إذا كنت تعرف قاعدة العميل لديك، فليس من الصعب أن تبني محتوى فيديو يُستَمتع به. لا تُضيع وقت العميل المهم. لابد من وجود سبب وجيه يجعل العملاء لديك يضغطون على الرابط الإعلاني الخاص بك، وبعد ذلك تأكد من أنهم سيكونون مسرورين بالمحتوى المرئي الذي سيرونه. استمر في المتابعة. فالجولة تتبعها جولة، لذا لا تبني محتوى فيديو منفصل عن بعضه البعض، واربط المحتوى بمحتوى اخر سيأتي في المستقبل. بناء سلسلة محتوى فيديو مترابط من الطرق القوية في بناء وزيادة الاهتمام بعلامتك التجارية وبتوجيه الانضمام لها. المستخدمون الذين يرون الفيديو الخاص بك لأول مرة سيبقون على اتصال لرؤية ما سيأتي، والذين يأتون لاحقا ويرون محتوى جذاب سيقومون بالعودة والنظر في المحتوى السابق لتفحص ما فاتهم. هذه ليست سوى بعض الطرق التي تُمكنك من الاستفادة من قوة محتوى الفيديو في صفحات الهبوط. لقد أصبح من المعروف منذ سنين لدى المسوقين مدى أهمية صفحات الهبوط ومحتوى الفيديو لذا من المهم الاستفادة من الجمع بينهما لصالح علامتك التجارية وللحصول على مستوى تحويل عالي وللبقاء قويًا في سوق يتميز بمنافسة عالية. ترجمة -وبتصرّف-للمقال How You Can Benefit from Video Landing Pages لصاحبه Stephen Moyers
  3. قد تبدو قوائم توزيع البريد الالكتروني والبريد الإلكتروني المشترك أبسط الطرق لمتابعة خدمة العملاء – في بعض الأحيان هم كذلك. إذا كنت تُمثّل شركة صغيرة الحجم -أو بدأت كشركة صغيرة- فقد يكون ذلك طبيعيًا. قد تكون استخدمت نظام Office 360 Microsoft Outlook لمعالجة قضايا العميل كلما ظهرت. ولكن الحلول السهلة والبسيطة لا تكون دائمًا الأفضل. فوضى قوائم توزيع البريد الإلكتروني وكذلك القيود الموجودة في برنامج البريد الإلكتروني المشترك لشركة مايكروسوفت تجعل الموظفين يشعرون بالإحباط وتجعل العملاء يتطلعون لتجربة أفضل قد يجدونها في مكان اخر إذا لم تُنشئ نظامًا جيدًا. عندما تعالج كل محادثات العملاء باستخدام أدوات مثل Gmail أو Outlook فمن السهل أنّ تتذكر لماذا قوائم التوزيع والبريد الالكتروني المشترك لم يتم بناؤهما لخدمة العميل. كلما تطورت الشركة، المنافع التي ستظهر من الانتقال لعملية مبسطة ستفوق بكثير المرحلة الأولى لمنحني التعلم والاستثمار لاستخدام نظام جديد. حلول الدعم من خلال البريد الإلكتروني هذه بعض الأدوات المختلفة قليلًا والمستخدمة على بناءً على البريد الالكتروني ولكنها تشكل تحدٍ لفرق الدعم: صندوق البريد الوارد المشترك صندوق بريد واحد يستخدم اسمًا مستعارًا (مثال: academy@hsoub.com). الرسائل الإلكترونية الواردة تظهر في هذا الصندوق المشترك. يستطيع الموظفون الدخول والرد مما يجعل ارسال الرد وكأنه من الاسم المستعار. قائمة توزيع البريد الإلكتروني هذه الأداة تَستخدم عنوان بريد إلكتروني مُخصص لمجموعة من الناس. إذا قام أحدٌ بإرسال بريد لهذه القائمة فإن البريد يصل لكل المشتركين فيها. يقوم الموظفون بالرد من عناوين بريدهم الخاصة. مجموعة Office 365 مصطلح "مجموعة" هو طريقة في Outlook للإتصال المشترك. انها تعمل كقائمة توزيع بريد إلكتروني ولكنها تحفظ الرسائل وتتضمن بريدًا مشتركًا، وتقويمًا، ومفكرةً ومكتبةً. مجموعة جوجل هذه أداة من جوجل تُمكنك من انشاء بريد إلكتروني مشترك أو قائمة توزيع من خلال بريد Gmail. خمس إشارات تحتاجها للانتقال من قائمة توزيع أو بريد مشترك إلى نظام الدعم الفني تدفق العمل الخاص بدعم العميل مهمُ جدًا لأنه يؤثر غالبًا على تجربة العميل. إذا كان أحدٌ ما غير سعيد بتجربة فإن أصغر خلل سيصل به إلى قرار المغادرة. إليك عدة إشارات واضحة تساعدك في التخلي عن حساب البريد الالكتروني المشترك والانتقال لنظام الدعم الفني: إذا كنت تتابع العملاء من خلال رسائل بريد الكتروني ولم يكن هناك ردًا على الاطلاق بعد عدة أيام. قيام أعضاء فريق بالرد على نفس العميل بشكل مُكرر أو بمعلومات متناقضة. الذي قام بذلك. ليس لديك تقارير عن حجم البريد الإلكتروني الذي تستقبله، أو سرعة رد الفريق، أو من هو الشخص الذي يقوم بالرد، أو ما مدى سعادة العملاء بالردود التي يقرأونها. دون عمل إعادة توجيه لرسالة البريد الإلكتروني لعدة أشخاص. وجود ما سبق يدل على أنك تستخدم قائمة توزيع وصندوق بريد مشترك وهذا يجعل شركتك تظهر بشكل غير محترف ويسلب من فريقك الإنتاجية. بمجرد ظهور أحد الدلائل السابقة، فهذا يعني أنه حان الوقت لبحث خيارات نظام الدعم الفني. ما الذي عليك البحث عنه في نظام الدعم الفني؟ كيف تبدأ عملية استكشاف نظام دعم فني جديد؟ فكر في البداية في أولوياتك، إذ تعلمنا في Help Scout أنه يوجد بعض العناصر الأساسية لا تستغني عنها أي شركة. عند حصولك على تلك المميزات تستطيع أن تُقدم خدمة عملاء أفضل دون الحاجة لحساب بريد إلكتروني مشترك. الشفافية غياب الشفافية مشكلة عامة في Office 360، حيث لا يوجد طريقة لمعرفة إذا كان الغير يعمل على حل نفس القضية في نفس الوقت. إذا كان لديك فريق بإنتاجية عالية فإن هذا قد يعمل ضد مصلحة الشركة حيث ستجد رسائل متعددة تُرسل من نفس العنوان وتحتوي نفس المضمون في وقت واحد. لك أن تتخيل حجم الإحباط الذي سيشعر به العميل عندما يفتح كل هذه الرسائل. خاصية Traffic Cop indicators في Help Scout تُظهر لكل شخص من الذي يعمل على أي قضية من قضايا العملاء وفي الوقت الحقيقي: انه نظام رسومي سهل: مثلث أصفر يُظهر أن مستخدمًا اخر يقوم بمراجعة المحادثة، والمثلث الأحمر يُشير الى أن شخصًا أخرًا يقوم بالرد على المحادثة. بالإضافة لذلك، Help Scout لا يسمح لك بإرسال رسالة لعميل إذا وُجد شخصٌ آخر ردّ خلال الوقت الذي كنت تعمل فيه على ذلك الرد. أنظمة الدعم الفني تُسهّل من التعاون لحل قضايا العملاء الصعبة. بدلًا من إعادة توجيه المشاكل للمشرفين أو باتجاه أعضاء الفريق الداخليين، تستطيع العمل على حل المشكلة مع الغير على منصة Help Scout. يستطيع المدراء تفحّص حالة قضية بشكل مباشر دون الحاجة للرجوع لكل شخص. المسؤولية أثناء تدفق العمل ستخسر كمًا كبيرًا من الإنتاجية عندما يعمل أكثر من موظف على نفس القضية. على الرغم من أن العميل لا يستقبل عدة ردود، ولكن مدة الوقت اللازم لحل مشكلة ما سيحبط العاملين لديك. تستطيع أن تحاول بناء حلول بديلة، ولكن في الحقيقة، القيود الموجودة في البريد المشترك لـ Office 360 تُكبل نظامهم. هناك بالتأكيد طريقة أفضل. مجلدات التعيين في نظام Help Scout تُظهر لك كل شيء تم تكليفه لفريقك. بإمكانك ترتيب القائمة حسب الشخص المُكلَف للتأكد من عدم ضياع أي شيء في حال خروج عضو ليوم أو مغادرته الشركة. تستطيع من هناك إزالة شخص من مهمة وربطها بشخص آخر. هذا الحل السهل يخلق الاستقرار ليس فقط للعاملين لديك، بل أيضًا لعملائك. تقارير لا تقدر بثمن عن عملائك وموظفيك أغلب أنظمة الدعم الفني الأساسية تُقدم تقارير عن العملاء أبعد بكثير من الذي يقدمه Office 360. التفاعل مع العملاء يكشف عن كنز معلومات: أكثر مشاكل تجربة العملاء، وما يحتاجه العملاء، وما هو الشيء الذي يجعل حياتهم أفضل خلال عملك. يُمًكِّنُك Help Scout من متابعة أغلب أنواع المقاييس الخاصة بعملائك وعملك. هذه بعضٌ منها: إجمالي المحادثات عدد العملاء الذين يحتاجون للمساعدة كل يوم أكثر الأيام والأوقات ازدحامًا بطلبات الدعم أشهر المواضيع التي يكتب عنها الناس التغير في الطلبات النموذجية فرص أتمته العمليات تستطيع تحسين كل جزء من عملك من خلال أدوات التقارير في Help Scout ابتداءً من عدد الموظفين الذين يعملون في كل وردية عمل الى حل القضايا المحورية في المنتج التي تؤدي لعدم رضا العميل. يقدم لك Help Scout تقارير عن أداء الأفراد وكفاءة الفريق بقياسات حديثة وواضحة. إذا قام أحدهم بإرسال بريد مرفوض لأحد العملاء ستعرف ذلك من أول يوم. كمدير، هذه التقارير تساعدك في السيطرة للوصول لكفاءة أكبر ونجاحات مثمرة. باختصار، مثل هذه التقارير هي طعامك وشرابك لقيادة فريق مميز. الانتقال من قائمة توزيع بريد إلكتروني أو بريد الكتروني مشترك لنظام دعم فني قد يبدو مُخيفًا، ولكنه يستحق التجربة. بطريقة مبسطة وشفافة لتدفق العمل خلال نظام دعم فني سيتمتع فرق العمل لديك بالقوة وتتلاءم مع تطور الشركة، مع التأكد من أن أفضل عملاءك لن ينزلق نحو مشاكل البريد الإلكتروني المشترك. ترجمة -وبتصرّف-للمقال How to Tell It’s Time to Ditch Your Shared Email Inbox لصاحبه Elizabeth Wellington
  4. تواجه الشركات الناشئة في عالم الأعمال العديد من العوائق في ظل التنافس الشديد في هذا العالم. أحد أبرز هذه العوائق هو تدني ثقة المستهلك، فلا يوجد أحد سيقدم ماله لجهة ما لا تمتلك تقييمات ومراجعات سابقة أو لا تمتلك كيانًا مضمونًا يمكن الرهان عليه. يوجد العديد من الحلول للمشكلة السابقة وأحد أكثر هذه الحلول فعالية هو التسويق باستخدام الشبكات الاجتماعية وتأييد الموظف هو أحد الأشكال الجديدة لهذا الحل. يميل الناس غالبًا للثقة بالتزكيات الغير احتفالية وخاصة من الأقران، لذلك فإن جعل الموظفين يتحدثون عن عملك سيكون مُفيدًا جدًا. ولكن كيف يُمكن تفعيل ذلك؟ وكيف يُمكنك تطبيق تقنية مُثمرة؟ فوضع خطة لجعل الموظف يتحدث عن عملك هو أمر سهل ولكن من الصعب إتقانه، لذلك من الأهمية بمكان جمع ما يمكنك من المعلومات من البداية. ما هو تأييد الموظف؟ عندما يقوم الموظفون بإعادة نشر أو إعادة تغريد منشوراتك وتأييدك في الشبكات الاجتماعية ومناقشة عملك مع الغير بشكل حي على شبكة الإنترنت فهذا هو تأييد الموظف في العالم الحديث. ويشمل ما سبق قيام الموظفين بمشاركة المحتوى المنشور من الغير والذي يخص الجهة المُوظِفة لهم. نستطيع أن نختصر ذلك بقيام العاملين بدعم شركتهم من خلال منصاتهم وحساباتهم الاجتماعية الخاصة بهم بدلًا من الاكتفاء بالقيام بذلك في الصفحات الرسمية والمشهورة فقط. على الرغم بمعرفة الجميع أن الإنترنت غيرت من طريقة ونهج قطاع الأعمال فيما يخص التسويق وجعلت الاعتماد على مساعدة الموظفين أمرًا نادرًا، ولكن هذا الأمر في الحقيقة أصبح مُعيبًا الأن لما يُشكله دعم الموظفين في زيادة ثقة المستهلك وزيادة عدد الزيارات لموقعك. كيف تستخدم تأييد الموظفين؟ بينما العديد من الشركات لديها برامج غير رسمية لتشجيع دعم الشركة من خلال الشبكات الاجتماعية عبر موظفيها، إلا أن هذه الطريقة صعبة في المتابعة كما أنها أقل فاعلية، فأنت تستطيع أن تجعل عينيك تراقب حسابات الموظفين ولكن من الصعب قياس مشاركة الموظف ومتابعة مدى التأثير الناتج عنه، بالإضافة لصعوبة متابعة حسابات العاملين مجتمعة. لحسن الحظ، يوجد منصات "شبكات اجتماعية مصغرة" تستهدف دعم الموظفين مثل LinkedIn Elevate, أو Smarp, أو Sociabble, أو Dynamic Signal. هذه المنصات تُقدم العديد من الخصائص والتحليلات. يسمح لك تتبع الارتباط "Link Tracking" برؤية أكثر المنشورات التي يتم الضغط عليها ورؤيتها، بالإضافة لأكثر محتوى شُهرةً وبذلك تزداد المنافسة لدى الموظفين للحصول على الصدارة وكسب النقاط والحصول على جوائز. هذه المنصات تجعل من السهل نشر المقالات لأن كل شيء يتم إدارته من مكان واحد ومريح، وهذا هو المفتاح إذا أردت أن تأخذ برنامج تأييد الموظفين في مؤسستك على محمل الجد. بهذه الطريقة، وبمجرد نشر المحتوى، فإن الموظفين يستطيعون بسهولة وسرعة مشاركة هذا المحتوى على الشبكات الاجتماعية المختلفة، وهو أمر أسهل من إرسال مذكرات يومية للموظفين لنشر ذلك على تويتر وفيس بوك. هذا النوع من الأدوات يقدم طريقة سهلة للموظفين ومُشغليهم للتواصل، التعاون والبقاء في صورة أخر المستجدات. قد يكون دور البريد الإلكتروني لم ينتهي بعد، ولكن المقدرة على وضع معلومات ذلت علاقة بالمؤسسة ونشرها من خلال تطبيق ما سيكون مريحًا أكثر بدلًا من إرسال بريد إلكتروني ضخم لمجموعة كبيرة من الموظفين. لماذا نحتاج دعم الموظفين؟ إذا أردت، فإنه من الممكن أن تُنشئ بعض حسابات تويتر للمدراء في شركتك، وتقوم بإعداد برنامج وظيفته هي إعادة نشر ما تقوم بإضافته في مدونتك أو صفحتك، وأن يعمل بشكل يومي، ولكن هذا الأمر لن يخرج عن إطار المألوف والمتعارف عليه. إن أغلب مستخدمي الشبكات الاجتماعية لديهم عين حساسة ويستطيعون ملاحظة الحسابات الآلية عن بعد ميل ولن يكون ذلك بالطبع جميلًا في حال استخدمت نفس الطريقة لحساب شركتك. إن المهتمين الذين يزورون حساباتك على المنصات الاجتماعية قد يتركوا متابعة هذه الحسابات بسبب المحتوى المشور بطريقة آلية. لذلك، فإن المحتوى المُثير الذي يتضمن لمسة حقيقة من شخص حقيقي بالإضافة لتفاعل المستخدم لهو أمر يحظى باحترام وتقدير الناس. قد تكون مشغولًا عن البقاء أمام الشاشة لمتابعة المنصات الاجتماعية، ولكن موظفيك قد لا يكونوا كذلك. يقل اهتمام المستهلكين هذه الأيام بالمدراء التنفيذين ويتجه التركيز نحو الشخص العادي، ناهيك عن أن المتابعين العاديين لديهم شبكات خاصة من الأصدقاء والأقران الذين يستطيعون الوصول لمحتواهم، وهذا الوصول للمحتوى هو أحد مفاتيح النجاح. من الواضح لحد ما أن ذلك هو وسيلة تسويق قيمة تستطيع توليد محتوى طبيعي وجذاب. لقد انتبهت الإنترنت لظاهرة Clickbait والحسابات الآلية، لذا فمن المهم الان بذل جهد إضافي لمواجهة ذلك. عندما نتحدث عن التأثير الاجتماعي، فإن الموظفون هم الذين يملكون ثقة الجمهور والعامة. تشجيع تأييد الموظفين بعد أن تعرفت على أهمية دعم الموظفين ولماذا أنت بحاجة له، يأتي السؤال المهم، كيف أستطيع تحفيز الموظفين للقيام بذلك؟ إذا كان نظام الدعم الذي تريده لا يُقدم للموظف حوافز ومكافئات أو تأثير إيجابي على وظيفتهم، فإنهم لن يضيعوا وقتهم في ذلك. عليك تقديم بعض التشجيع لذلك. في البداية، إن إجبار الموظف على الحديث عن شركتك في الشبكات الاجتماعية ليس هو الطريق، حيث تقل المعنويات حتى تنعدم عند إجبار الناس على القيام بشيء لا يهتمون به، وبدلًا من ذلك، حفزهم وزد اهتمامهم بما يقومون به. قم بتطبيق نظام مكافئات أو لائحة صدارة حتى تزيد المنافسة بينهم. تجنب إعطاء فقرات كبيرة من القواعد والقوانين المعقدة، وقم بتجهيز تعليمات مُختصرة وواضحة تسمح للعاملين لديك بأخذ زمام المبادرة وتوليد ونشر المحتوى الذي يستمتعون به ويرونه مناسبًا. سيعرف عملائك متى أن الموظفين لديك يحبون ما يقومون به وستكسب بذلك ثقة كليهما. الشيء المهم هو: لا تُملي كل حركة. القواعد مُهمة، ولكن لا تتطرف فيها. قد يظهر أنه من الخطر أن تمنح شخصًا حرية واسعة للتأثير في صورة شركتك، ولكن المكافئات التي سيحصل عليها الموظف مهمة بالنسبة له. هذه العقيدة تمنح الموظف القدرة على إنشاء محتوى حقيقي ليس كالمحتوى المُنشأ من قبل برنامج ألي أو في مصنع. ربما تسمح أيضًا لهم بإنشاء محتواهم الخاص. الكتاب المبدعين، الفنانين ومحررو الصور والفيديو يُشكلون اصلًا من أصول شركتك إذا استطعت اكتشافهم. أنشئ محتوى ذو صلة عندما لا يملك طاقمك شيئًا لمشاركته، فعن ماذا سيتكلمون إذن؟ إذا لم تكن في خضم الشبكات الاجتماعية بشكل قوي فإنه حان الوقت للبدء بذلك. أدخل توتير، اكتب في فيسبوك وابدأ في كتابة منشوراتك وتغريداتك. بجانب جذب اهتمام إضافي لشركتك، سيكون من الجيد توفير مادة قابلة لإعادة النشر وفتح السبيل للنقاش بين الموظفين ولا تنس إضافة المرح إذا استطعت. فإذا كانت شركتك تُقيم حفلًا قم بالتقاط الصور وانشرها في المحتوى. محتوى كهذا سيقدم نَفَسًا نقيًا لصفحتك ويضع عملائك في وسط مناخ الشركة. باختصار، فإن أيًا ما تنشره في الشبكات الاجتماعية لابد أن يكون ثاقبًا أو جديرًا بالذكر ومَرِحًا. مشاركة مواضيع ذات عناوين عفوية، ذات صلة وتحتوي على صور أو فيديوهات سريعة، كل ذلك هو مناسب. تبني هذه الفكرة العامة سيفيد شُهرتك على المنصات الاجتماعية بالإضافة لبرنامج تأييد الموظفين لديك. طور إستراتيجيتك التسويقية باستخدام تطبيق التأييد الطريقة المؤكدة لتطبيق خطة التسويق هو باستخدام منصة تشبيك. يوجد العديد من التطبيقات التي تساعد في ذلك، ولكن من الأفضل أن تختار تطبيقًا يشمل تأييد الموظفين. تطبيقات مثل هذه تُغطي أغلب الخصائص التي تُقدمها تطبيقات التشبيك للأعمال، بالإضافة أنها تُقدم تحليلات ذات صلة تُساعدك في معرفة ما هو المحتوى الذي تستهدفه وما هي طبيعة العملاء المهتمين في الشركة. دون ذلك، عليك الاعتماد على أتباع وقياس كفاءة ذلك – وهذا غالبًا غير جدير بالثقة. ابدأ بشكل صغير وابحث عن أفضل العاملين لديك الذين يتسمون بالحرص وحب تجربة الأشياء الجديدة. نفذ مسابقات وحدد الأهداف المطلوبة منهم، وإذا نجحوا قم بعرض ذلك على الموظفين الذين يرغبون بالمشاركة حتى تصل لبرنامج مستقر. ومع الوقت، سيكون لديك برنامج ناجح قام بكل من زيادة عدد الزائرين وإعطاء الفرصة للعاملين لديك لتعزيز مهاراتهم ووظائفهم. الأمر يستحق التجربة، فالمخاطر قليلة ولكن الفائدة هائلة. ترجمة -وبتصرّف- للمقال Why Employee Advocacy Must Be Part of Your Social Media Marketing Plan لصاحبه Brenda Stokes Barron
  5. اذا كان حسابك قديم، وحتى لو كنت مُنشئ تطبيقات عليه، ستحتاج الان إلى ان تملأ الطلب وترسله ثم بعد الموافقة عليه تستطيع إنشاء تطبيقات جديدة
  6. وعليكم السلام،،، لم يعد بالامكان حاليًا ان تُنشئ تطبيق بشكل مباشر على حساب مطوري تويتر إلا بعد ان تُقدم طلب Application لهم ومن ثم يراجعونه. بعد موافقتهم تستطيع ان تُنشئ التطبيق وتُطبق المثال الموجود في المقال. تحياتي وبالتوفيق
  7. في جو العمل، يوجد العديد من الطرق التي تُساعدك في تخفيض التكاليف وتوفير الوقت وزيادة الأرباح. قد يبدو مصطلح "نصائح التسويق" جذابًا، ولكن هل هي مفيدة لصالح العلامات التجارية؟ تُشير الدلائل إلى أن النصائح المناسبة في الوقت المناسب تُسرع من الحملات التسويقية دون إنفاق المزيد من المال. هذه ثمانية نصائح لتحسين جهودك التسويقية من دون مشاحنات. حدث محتواك المتجدد يبقى المحتوى المتجدد مُهمًا لسنوات-أو على الأقل خلال المستقبل المنظور. هذا المحتوى هو الذي يجعل قُراءَك يبحثون عنه دائمًا. عناوين مثل "أهم المصطلحات الصناعية" أو "كيف تقوم بـ " هي عناوين لا تفقد عنفوانها مع الزمن. المحتوى المتجدد في موقعك سيُحسن من أدائه في محركات البحث ويبقى أثره لمدة طويلة. بالإضافة إلى ذلك فهو لا يحتاج لمتابعة دائمة حيث لا تحتاج لتحديث المحتوى المتجدد بشكل دوري. نشر المحتوى المتجدد يُميز شركتك كأحد المصادر المهمة في السوق الذي تعمل فيه، ويمنحك عوائد تسويقية بقليل من الجهد بمجرد إنشائه. كنصيحة تسويقية، يجب أن يكون عُمر المحتوى المتجدد طويلًا حتى تستفيد منه. لابد من إعطاء الأولوية لجودة المحتوى، وأضف لذلك وجود روابط تُوجه الزوار لهذا المحتوى بشرط أن تكون هذه الروابط موجودة في مصادر ذات سمعة حسنة ومشهورة وألا تنتهي صلاحية هذه الروابط. تحتاج أيضًا لاستخدام عناوين تُلبي حاجات جمهورك ولها علاقة بما يهتمون به. يجب أن يكون المحتوى المتجدد مقروءًا بشكل واضح، مع وجود بعض العناوين والنقاط التي تُقسم الفقرات الطويلة في المحتوى. المحتوى يجب أن يكون أطول من المواضيع العادية في المدونة وذلك حتى تُقدم محتوى ذُو قيمة للقراء، وكلما مكث القُراء أطول في الموقع كلما حصلت على نقاط أفضل في ترتيب البحث في جوجل. أعد نشر المحتوى القديم مع التحديثات نشر المحتوى الجديد هو أمر مُهم لموقعك ولكنه لا يجب أن يكون النوع الوحيد من المحتوى الذي تُسوقه. ابحث في المحتوى القديم واختار منه الذي له صلة بالجمهور أو الذي يهتمون به. بعد ذلك، أضف بعض التعديلات والتحديثات للمعلومات وأعد نشرها في موقعك وحساباتك الاجتماعية. استخدم كلمات مثل "تحديث" أو "معلومات جديدة" لإبلاغ جمهورك أنك قمت بإضافة شيء ذو صلة بموضوع قديم. تكرار المحتوى طريقة سريعة وسهلة للبقاء متصلًا ومشاركًا دون الحاجة لوقت أو تكاليف. راجع استراتيجية السيو لديك قد يكون التهيئة لمحركات البحث موضوعًا مُكررًا، ولكنه ذو أهمية كبيرة لنجاح جهود التسويق لديك. راجع استراتيجيات التهيئة التسويقية لمحركات البحث وتأكد أنك لا تُضيع المال أو الفرص. فمثلًا، قم بفحص الكلمات المفتاحية غير النموذجية وتأكد هل تستحق الاستثمار أم لا، فقد تجد أن بعض الكلمات المفتاحية الأخرى مهمة أكثر لشركتك. أزل البقية التي ليس لها علاقة واحفظ موازنة التسويق ببساطة ودون عناء. استخدم أدوات مثل Google Keyword Planner او Google Trends للبحث عن المواضيع الساخنة التي يهتم بها جمهورك. يساعدك مخطط جوجل للكلمات المفتاحية في اكتشاف جديد الكلمات المفتاحية التي لها علاقة بمحتواك، وتمكنك من مقارنة اتجاهات الكلمات المفتاحية وأحجام البحث فيها، بالإضافة أنها تساعدك على إنشاء المجموعات وإعداد العروض. راقب آخر الأخبار الخاصة بمجال عملك واستخدم الكلمات المفتاحية المتعلقة بالموقع الجغرافي في إعداد التهيئة المحلية لمحركات البحث Local SEO – إرسال موقع شركتك الجغرافي إلى محركات البحث-. تحقق من منافسيك وتفقد الكلمات المفتاحية التي تعمل لصالحهم. بإمكانك استخدام منصة مدفوعة الأجر مثل Moz.com لإجراء تهيئة الكلمات المفتاحية دون عناء. أعد تسويق محتواك إعادة تسويق المحتوى هو أفضل أصدقائك، حيث يساعدك في متابعة المستخدمين الذين يزورون موقعك ولم يقوموا بإجراء عملية شراء. هؤلاء المستهلكين سوف يرون محتواك في مكان آخر مثل الفيس بوك أو اليوتيوب. يمنحك إعادة التسويق فرصة ثانية لتكون علامة تجارية ذات قيمة للمستهلك. إنه يذكر المستخدمين بإكمال الإجراء الذي بدأوه بزيارة موقعك، ويعمل كطريقة لجعلهم يبقون على اتصال. أعد تسويق محتواك باستخدام الكوكيز، إعلانات البانر وتكتيكات التسويق لجمهور محدد. أدوات مثل Google Display Network و Facebook Remarketing تساعدك في أغلب ما تم ذكره في هذه النصيحة. عُد الى جمهورك المستهدف مع مرور الوقت سيكون من السهل خسارة جمهورك الذي تستهدفه وتحاول جذبه لمحتواك. من الجدير بك أن تتفحص بشكل دوري الجمهور الذي تستهدفه وما يجب عليك فعله بشكل مغاير لتُبقي حملاتك التسويقية مثيرة وممتعة وذات طابع. حلل إعلاناتك واعرف أيًا من حملاتك التسويقية تعود بالنتائج المرجوة منها. قد تكتشف أنك تقوم بأخطاء صغيرة مثل وجود تناقض في العلامة التجارية وهذا سيؤثر على نجاح إعلاناتك. يجب أن تعمل صفحات الهبوط في جميع الأوقات، ويجب أن يرى إعلاناتك مستخدمون ذَوُو علاقة. إذا قمت بالانتقال من فيس بوك الى الانستقرام أو سناب شات مثلًا، عليك أن تكون على رأس التغييرات التي تحدث في ذلك، وأن تقوم بإعادة تفصيل المحتوى وترتيبه ليناسب المنصات الجديدة. راجع دائمًا الفئات العمرية، الجنس والتركيبات السكانية. القيام بذلك سيساعدك في تجنب الإنفاق الغير مجدي على إعلانات تفقد درجتها وتفشل في تحويل جمهورك الى عملاء. راجع مدونتك لا تدع مدونتك تسقط وتحيد عن الطريق بينما تُركز على جهودك وحملاتك التسويقية الأخرى. مدونتك أساسية في نجاح التسويق لعلامتك التجارية. قضاء بعض الساعات أسبوعيًا في تهيئة مدونتك، إنشاء محتوى جديد، والنشر بانتظام، كل ذلك يُسرع في انضمام المستخدمين لك. تذكر النصائح البسيطة التالية: حدث المدونة أولًا بأول. إذا أصبحت المدونة قديمة وليست على علاقة بمحتواك الذي تسوقه، فإن ذلك يؤذي موقعك بشكل جيد. عليك بالنشر بشكل ثابت، فمحرك جوجل يعتني بالمواقع التي تنشر محتوى بشكل دوري، لذا فإن تحديث المدونة أولًا بأول يُسرع من تهيئة الموقع لمحركات البحث ويُحسن من ظهوره في نتائج البحث وبكل تأكيد سيزيد من ظهور علامتك التجارية. اجعل مدونتك ذات طابع. القراء الحاليين يرغبون بالشعور بارتباط حقيقي مع العلامات التجارية. مدونتك هي الخيار الأنسب لتقديم فرصة المشاركة والارتباط بعلامتك التجارية بالإضافة لتقديم محتوى ذو طابع مرغوب. ادرس جمهورك الذي تستهدفه جيدًا واكتب لأشخاص مُعينين. وظف محترف. إذا لم يكن لديك متسع من الوقت والطاقة الضروريان لمتابعة مدونتك، عليك بتوظيف كاتب محتوى محترف. لا تنسى النصائح والممارسات الجيدة التي تساعدك في اختيار الكاتب الجيد، واعتمد الموازنة التي تناسبك. باستخدام المصادر والأدوات الصحيحة، ستكون متابعة المدونة أمرًا سهلًا ومربحًا للغاية. قم بمتابعة المدونة بشكل دوري للتأكد أنها تعمل بالشكل المطلوب. تهيئة المدونة يُحسن من جهود الحملات التسويقية دون الكثير من العمل المطلوب من طرفك. أشعل حملاتك أنشئ ملف مراجع swipe file خاص بعملك ودَون فيه الأفكار والإلهامات المستقاة من منافسيك ومن المواقع التي تحبها. احفظ الصور والتصميمات التي تعتقد أنها مناسبة لعلامتك التجارية والتي من الممكن أن تستفيد منها في المستقبل، ودون أفكار المحتوى الذي ستكتبه. يجب أن يكون ملف المراجع الخاص بك كالكنز الذي يحوي التفكير المبدع والأفكار الجديدة لشركتك. عندما تحتاج بعضًا من الإلهام افتح ملف المراجع الخاص بك واستخدم الأفكار الموجودة فيه لإشعال حملاتك التجارية التي أصبحت مملة أو التي فشلت في جذب الجمهور الذي تبتغيه. ملف المراجع حلٌ بسيط للبقاء في الأمام أثناء لعبة الحملات التسويقية وذلك دون الحاجة لكثير من الوقت والجهد. لا تنسى أصلك قبل كل شيء، إياك ان تبتعد عن المهمة الرئيسية لعلامتك التجارية. في بعض الأحيان، تحتاج الحملات التسويقية المتخبطة أن تتذكر الأهداف الرئيسية لها. ما هي المهمة الرئيسية الخاصة بك – إنقاذ الكوكب مثلًا؟ تبسيط مهام العمل؟ جعل حياة عملائك أسهل؟ تذكر دائمًا مهمتك الرئيسية أثناء عملك وجهودك التسويقية حتى تُقدم للعالم رسالة واحدة ومتماسكة. الرجوع للأصل يُذكر عملائك بالسبب الذي جعلهم ينضمون لك في البداية. قد يُدهشك حجم الإلهام التسويقي الذي ستجده عندما تتذكر السبب الكامن خلف انطلاقك العمل. كن وفيًا لعملك والباقي سيأتي تباعًا. ترجمة -وبتصرّف-للمقال 8 Quick Tips to Boost Your Web Marketing Campaigns لصاحبه Stephen Moyers
  8. أهلًا بكم
  9. المصفوفة في الجافا سكريبت تتكون من قائمة عناصر، وتتيح الجافا سكريبت للمبرمجين العديد من الوظائف التي تعمل على المصفوفات. الوظائف التي تقوم بالتعديل على المصفوفة الأصلية تُعرف بتوابع التعديل (Mutator Methods)، والوظائف التي تُعيد قيمة جديدة أو شكل آخر من المصفوفة تُعرف بتوابع الوصول (Accessor Methods). يوجد نوع ثالث من التوابع يُسمى بتوابع التكرار (Iteration Methods) والتي سنتناولها بالشرح في هذا المقال. تُتيح توابع التكرار العمل على كل عنصر في المصفوفة كلٌ على حدة، وترتبط هذه التوابع بشكل أساسي بحلقات التكرار. للاستفادة أكثر من هذا الدرس، يجب أن يكون لديك معرفة مُسبقة بكيفية إنشاء المصفوفات، فهرستها، التعديل عليها والمرور على عناصرها بواسطة حلقة التكرار. تستطيع مراجعة درس فهم المصفوفات في الجافا سكريبت لأخذ فكرة عما سبق. ما سنتناوله في هذا الدرس يشمل شرح استخدام وظائف التكرار لتنفيذ حلقة التكرار على المصفوفات وإجراء عمليات على كل عنصر في المصفوفة، توضيح كيفية ترشيح نتائج العمل على المصفوفة، تلخيص عناصر المصفوفة في قيمة واحدة والبحث عن قيم وفهارس معينة. فهم الدوال السهمية (Arrow Functions) العديد من الأمثلة في هذا المقال ستستخدم صيغة الدوال السهمية في الجافا سكريبت والتي يتم تمثيلها بواسطة علامة المساواة ثم علامة الأكبر من <=. الدالة في الجافا سكريبت عبارة عن كتلة من الشيفرة البرمجية يتم تنفيذها وإعادة استخدامها أكثر من مرة، وعادةً ما تُكتب وفق الصيغة التالية: var example = function() { // code to execute } example(); النسخة الأخيرة من الجافا السكريبت -حتى وقت كتابة هذا الدرس- تسمح باستخدام الدوال السهمية والتي تُكتب وفق الصيغة التالية: var example = () => { // code to execute } example(); في الدوال السهمية تُكتب الأقواس لاستقبال معاملات الدالة. في حالة كان لدينا مُعامل واحد فقط فنستطيع حينها التخلي عن كتابة الأقواس كما في الصيغة التالية: var example = parameter1 => { // code to execute } سنعتمد في شرح هذا الدرس على الدوال السهمية، وللاطلاع أكثر على هذا الموضوع، تستطيع الذهاب الى هذا المرجع . الوظيفة ()forEach تقوم الوظيفة ()forEach باستدعاء دالة ليتم تنفيذها على كل عنصر في مصفوفة معينة. فمثلًا، نفترض وجود المصفوفة fish بالعناصر التالية: let fish = [ "piranha", "barracuda", "cod", "eel" ]; نستطيع استخدام الوظيفة ()forEach لطباعة كل عنصر في المصفوفة fish على الطرفية: // Print out each item in the array fish.forEach(individualFish => { console.log(individualFish); }) Output piranha barracuda cod eel يوجد طريقة أخرى لعمل ما سبق وذلك باستخدام جملة التكرار for بالإضافة لاستخدام الخاصية length: // Loop through the length of the array for (let i = 0; i < fish.length; i++) { console.log(fish[i]); } استخدام جملة for السابقة في طباعة كل عنصر على حدة يعطينا نفس النتيجة عند استخدام ()forEach، ولكن استخدام الطريقة ()forEach يُعتبر خيارًا مختصرًا ومباشرًا وأفضل لمثل هذه الحالات. الوظيفة ()map تقوم الوظيفة ()map ببناء مصفوفة ناتجة عن استدعاء دالة على عناصر مصفوفة أخرى. نستطيع طباعة عناصر مصفوفة عنصر-عنصر كمثال توضيحي على كيفية استخدام وظيفة ()map ولكن على العكس من الوظيفة ()forEach، لابد من حفظ ناتج الوظيفة في متغير جديد. let fish = [ "piranha", "barracuda", "cod", "eel" ]; // Print out each item in the array let printFish = fish.map(individualFish => { console.log(individualFish); }); printFish; Output piranha barracuda cod eel مثال أخر على استخدام الوظيفة ()map، حيث نستطيع أيضًا أن نُغير قيمة كل عنصر في مصفوفة وحفظ العناصر الجديدة الناتجة عن هذا التغيير في مصفوفة أخرى. فمثلًا، يمكننا إضافة الحرف s الى نهاية كل عنصر في المصفوفة fish لجعل الأسماء أسماء جمع. // Pluralize all items in the fish array let pluralFish = fish.map(individualFish => { return `${individualFish}s`; }); pluralFish; Output [ 'piranhas', 'barracudas', 'cods', 'eels' ] المصفوفة الأصلية fish لم تتغير، ولكن المصفوفة الجديدة pluralFish أصبحت الان تحتوي على النسخة المُعدلة من المصفوفة الأصلية. الوظيفة ()filter تقوم الوظيفة ()filter بإنشاء مصفوفة جديدة تحتوي على عناصر من المصفوفة الأصلية تتوافق مع شرط معين. الهدف الرئيسي من هذه الوظيفة هو إجراء عملية الترشيح، فمثلًا، نستطيع أن نحصل من الوظيفة ()filter على مصفوفة جديدة تحتوي على العناصر التي تبدأ بحرف مُعين، وذلك بالاستفادة من خاصية فهرسة النصوص التي تُمكننا من الحصول على الحرف الأول لكل عنصر. let seaCreatures = [ "shark", "whale", "squid", "starfish", "narwhal" ]; // Filter all creatures that start with "s" into a new list let filteredList = seaCreatures.filter(creature => { return creature[0] === "s"; }); filteredList; Output [ 'shark', 'squid', 'starfish' ] في المثال السابق اختبرنا جميع العناصر التي تبدأ بالحرف s وحفظنا النتيجة في مصفوفة جيدة باسم filteredList. الوظيفة ()reduce تقوم الوظيفة ()reduce باختصار مصفوفة في قيمة واحدة، وعادةً يُرى هذا الاستخدام مع المصفوفات التي تحتوي على أرقام، مثل الحصول على مجموع عناصر مصفوفة: let numbers = [ 42, 23, 16, 15, 4, 8 ]; // Get the sum of all numerical values let sum = numbers.reduce((a, b) => { return a + b; }); sum; Output 108 تُستخدم الوظيفة ()reduce أيضًا مع النصوص وأنواع البيانات الأخرى، وتكون القيمة المُرجعة من الوظيفة إما رقم أو نص أو أي نوع بيانات أخر. الوظيفة ()find تُعيد الوظيفة ()find أول عنصر من مصفوفة يتوافق مع شرط مُعين. لتوضيح ذلك، سوف نُنشئ مصفوفة تحتوي على أسماء مخلوقات بحرية، وسنستخدم الوظيفة ()find في إيجاد المخلوقات البحرية ذات النوع الرخوي مثل الأخطبوط (من الرخويات). let seaCreatures = [ "whale", "octopus", "shark", "cuttlefish", "flounder" ]; // Check if a given value is a cephalopod const isCephalopod = cephalopod => { return [ "cuttlefish", "octopus" ].includes(cephalopod); } seaCreatures.find(isCephalopod); Output Octopus بما أن “octopus” هو العنصر الأول في المصفوفة seaCreatures الذي ينطبق عليه الشرط، فإنه هو القيمة الأولى التي تم إرجاعها. نستفيد من الوظيفة ()find في عملنا مع المصفوفات التي تحتوي على قيمة عديدة. الوظيفة ()findIndex تُعيد الوظيفة ()findIndex فهرس أول عنصر من مصفوفة يتوافق مع شرط مُعين. سنستخدم نفس المثال السابق في وظيفة ()find لإيجاد فهرس أول عنصر من المصفوفة من النوع الرخوي. let seaCreatures = [ "whale", "octopus", "shark", "cuttlefish", "flounder" ]; باستخدام المصفوفة isCephalopod مع الوظيفة ()findIndex سنحصل على رقم الفهرس للعنصر بدلا من قيمته. // Check if a given value is a cephalopod const isCephalopod = cephalopod => { return [ "cuttlefish", "octopus" ].includes(cephalopod); } seaCreatures.findIndex(isCephalopod); Output 1 العنصر “octopus” هو العنصر الأول من المصفوفة الذي ينطبق عليه الشرط وموقعه في الفهرس رقم 1 وهي القيمة التي حصلنا عليها. في حالة لم ينطبق الشرط على أية عنصر في المصفوفة، فإن القيمة المرجعة هي -1. const isThereAnEel = eel => { return [ "eel" ].includes(eel); } seaCreatures.findIndex Output -1 خاتمة في هذا الدرس قمنا بمراجعة أغلب وظائف توابع التكرار في الجافا سكريبت. وظائف التكرار تعمل على كل عنصر في المصفوفة كلٌ على حدة وغالبًا ما يتم تطبيق دالة جديدة معها. تم شرح كيفية المرور على المصفوفة وعناصرها من خلال حلقة تكرار، تغيير قيمة العنصر في المصفوفة، ترشيح المصفوفة، اختصار المصفوفة في قيمة واحدة والبحث في المصفوفة باستخدام قيم العناصر او فهارسها. لأخذ فكرة عن المصفوفات تستطيع الاطلاع على درس فهم المصفوفات في الجافا سكريبت . ترجمة -وبتصرّف- للمقال How To Use Array Methods in JavaScript: Iteration Methods لصاحبته Tania Rascia حقوق الصورة البارزة محفوظة لـ Freepik
  10. المصفوفة في جافا سكريبت هي نوع من أنواع البيانات المتاحة فيها وتتكون من قائمة من العناصر. تحتوي الجافا سكريبت على العديد من الوظائف المُرفقة والتي تعمل على المصفوفات. الوظائف التي تقوم بالتعديل على المصفوفة الأصلية تُعرف بتوابع التعديل (Mutator Methods)، والوظائف التي تُعيد قيمة جديدة أو شكلًا آخر من المصفوفة تُعرف بتوابع الوصول (Accessor Methods). في هذا المقال سنتحدث عن توابع الوصول. للاستفادة أكثر من هذا الدرس، يجب أن يكون لديك معرفة مسبقة بكيفية إنشاء المصفوفات، فهرستها، التعديل عليها والمرور على عناصرها بواسطة حلقة التكرار. تستطيع مراجعة درس فهم المصفوفات في الجافا سكريبت لأخذ فكرة عما سبق. هذا الدرس يوضح كيفية دمج المصفوفات ببعضها، تحويل المصفوفات الى نصوص، نسخ أجزاء من مصفوفة وحفظها كمصفوفة جديدة بالإضافة لتحديد فهارس المصفوفة. الوظيفة ()concat تقوم الوظيفة ()concat بدمج مصفوفتين أو أكثر ببعضها البعض لينتج لدينا مصفوفة جديدة. في المثال التالي نقوم بإنشاء مصفوفتين تحتويان على أنواع الأسماك الصدفية ومن ثم نقوم بدمجهما في مصفوفة واحدة. // Create arrays of monovalves and bivalves let monovalves = [ "abalone", "conch" ]; let bivalves = [ "oyster", "mussel", "clam" ]; // Concatenate them together into shellfish variable let shellfish = monovalves.concat(bivalves); بمجرد استدعائنا للمصفوفة الجديدة، سنرى أنها تحتوي على العناصر الموجودة في كلا المصفوفتين السابقتين. shellfish; Output [ 'abalone', 'conch', 'oyster', 'mussel', 'clam' ] نستطيع تمرير أكثر من مُعطى للوظيفة ()concate لتسمح لنا بكفاءة وبخطوة واحدة أن ندمج مجموعة مصفوفات ببعضها البعض. الوظيفة ()join تقوم الوظيفة ()join بتحويل جميع عناصر مصفوفة معينة إلى قيمة نصية. في المثال التالي، تقوم الوظيفة بعملية تحويل عناصر المصفوفة fish الى قيمة نصية. لاحظ أنه بدون أن نُمرر أي معطى للوظيفة ()join سيتم فصل عناصر المصفوفة عن بعضها بواسطة فاصلة عادية وذلك في القيمة النصية الناتجة. let fish = [ "piranha", "barracuda", "koi", "eel" ]; // Join the elements of an array into a string let fishString = fish.join(); fishString; Output 'piranha,barracuda,koi,eel' اذا أردنا أن يتم فصل العناصر عن بعضها البعض بواسطة مسافة أو أي فاصل اخر، فعلينا أن نضيف الفاصل الذي نرغب به كمُعطى للوظيفة ()join. // Join the elements of an array into a string let fishString = fish.join(', '); fishString; Output 'piranha, barracuda, koi, eel' في المثال السابق، مررنا الفاصل ‘, ’ الذي يحتوي على فاصلة عادية ومسافة وذلك لفصل عناصر المصفوفة ولكي نحصل على نص مقروء بطريقة أفضل. في حالة قمنا بتمرير فاصل فارغ للوظيفة ()join، فإن الفاصلة التلقائية سيتم ازالتها بالكامل. الوظيفة ()slice نستخدم الوظيفة ()slice لنسخ أجزاء من مصفوفة إلى مصفوفة أخرى جديدة. let fish = [ "piranha", "barracuda", "koi", "eel" ]; لنفترض أننا نربد نسخ أخر عنصرين في المصفوفة fish الى مصفوفة جديدة، فإننا سنبدأ بالنسخ من الفهرس 2 الذي يمثل موقع العنصر “koi” وسينتهي النسخ عند رقم الفهرس الذي يلي فهرس أخر عنصر نريد نسخه. بما أن فهرس أخر عنصر “eel” هو 3، فإننا سنمرر للمعطى الثاني القيمة 4. // Slice a new array from 2 to 5 let fishWithShortNames = fish.slice(2, 4); fishWithShortNames; Output [ 'koi', 'eel' ] في هذه الحالة الخاصة، وبسبب أن العنصر “eel” هو أخر عنصر في المصفوفة، فإن المُعطى الأخير في الوظيفة ()slice غير ضروري، حيث أن النسخ سيبدأ من فهرس البداية وينتهي لنهاية المصفوفة عند عدم تمرير المعطى الثاني. // Slice a new array from 2 to the end of the array let fishWithShortNames = fish.slice(2); fishWithShortNames; Output [ 'koi', 'eel' ] انتبه ألا يختلط عليك الأمر مع وظيفة توابع التعديل المسماة ()splice والتي تقوم بإضافة أو حذف العناصر من المصفوفة الأصلية. الوظيفة ()indexOf تُعيد هذه الوظيفة رقم الفهرس لأول وجود لعنصر معين في مصفوفة، وتظهر فائدة هذه الوظيفة بشكل واضح في المصفوفات التي تحتوي قيم عديدة ومتكررة. في المثال التالي، يتكرر وجود العنصر”barracuda” مرتين في المصفوفة fish. let fish = [ "piranha", "barracuda", "koi", "barracuda" ]; باستخدام الوظيفة ()indexOf نستطيع الحصول على موقع العنصر الأول من القيمة “barracuda”. // Find the first instance of an element fish.indexOf("barracuda"); Output 1 إذا قمنا بتمرير قيمة غير موجودة في المصفوفة فإن نتيجة الوظيفة ستكون القيمة الخاصة -1. fish.indexOf("shark"); Output -1 الوظيفة ()lastIndexOf تُعيد هذه الوظيفة رقم الفهرس للوجود الأخير لعنصر معين في مصفوفة. نستطيع اختبار هذه الوظيفة على نفس المثال السابق الذي يحتوي على تكرار القيمة “barracuda” مرتين. let fish = [ "piranha", "barracuda", "koi", "barracuda" ]; // Find the last instance of an element fish.lastIndexOf("barracuda"); Output 3 الوظيفة ()lastIndexOf تبدأ بالبحث عن العنصر ابتداءً من نهاية المصفوفة وبذلك فهي فعليًا تعيد فهرس أول عنصر تجده أثناء عملية البحث. خاتمة من خلال هذا الدرس قمنا بمراجعة وظائف توابع الوصول المرفقة مع مصفوفات الجافا سكريبت. توابع الوصول تقوم بإنشاء نسخة جديدة من المصفوفة بعكس توابع التعديل التي تقوم بتغيير المصفوفة الأصلية. تعلمنا كيفية دمج مصفوفتين أو أكثر، تحويل عناصر المصفوفة الى مجموعة قيم نصية مُجزأة بفاصلة عادية بالإضافة الى كيفية نسخ أجزاء من المصفوفة الى مصفوفة جديدة. وفي النهاية تعلمنا كيفية الحصول على فهرس أول وجود لعنصر أو أخر وجود له في مصفوفة معينة. لمراجعة أساسيات المصفوفات، راجع درس فهم المصفوفات في الجافا سكريبت. ترجمة -وبتصرّف- للمقال How To Use Array Methods in JavaScript Mutator Methods لصاحبته Tania Rascia
  11. مقدمة تُعتبر خدمات تخزين البيانات المرنة والقابلة للتوسع حسب الحاجة، متطلب أساسي لأغلب التطبيقات والخدمات التي يتم تطويرها بالأدوات والتقنيات الحديثة. بغض النظر عن تخزين كميات قليلة أو كثيرة من الصور، الفيديوهات والنصوص الضخمة فإن مُطوري التطبيقات يحتاجون حلًا لتخزين واسترجاع المحتوى الخاص بالمستخدم، سجلات عمله، نسخه الاحتياطية وغيره من الأمور الأخرى. في ظل الأنظمة المنشورة المعقدة، وفي ظل الحاويات المختلفة والبيئات سريعة التغير والزوال، فإن زمن حفظ الملفات ببساطة في وحدة تخزين على خادوم واحد قد انتهى، حيث قام مزودو الخدمات السحابية بتطوير خدمات لتلبية حاجات التخزين في الأنظمة والتطبيقات الحديثة، وغالبًا تندرج خدمات التخزين السحابية تحت نوعين هما التخزين الكائني (Object Storage) والتخزين الكتلي (Block Storage). سنتناول هنا مميزات وسلبيات كل نوع. ما هو التخزين الكتلي؟ تعتبر خدمات التخزين الكتلي بسيطة ومألوفة نوعًا ما، حيث تُقدم هذه الخدمات خدمة التخزين العادية –كما في القرص الصلب– ولكن من خلال الشبكة. يقدم مزودو الخدمات السحابية الأدوات اللازمة التي تُتيح الحصول على جهاز تخزين كتلي بأي حجم وربطه بالآلة الافتراضية الخاصة بك، ومن هنا تستطيع التعامل مع الجهاز كقرص عادي، حيث تستطيع تهيئته، حفظ الملفات عليه، ربط أكثر من قرص بنظام RAID أو حتى إعداد قاعدة بيانات عليه للكتابة مباشرةً على الجهاز الكتلي. بالإضافة لما سبق، فإن أجهزة التخزين المرتبطة بشبكة غالبًا ما تتميز عن الأقراص الصلبة العادية بما يلي: تستطيع أخذ نسخة حية بسهولة للجهاز للأغراض الاحتياطية. من الممكن إعادة تغيير حجم جهاز التخزين الكتلي وتلبية الاحتياجات المتراكمة. تستطيع فك وربط الجهاز بين الآلات الوهمية بسهولة. ما ذكرناه من مميزات هي خصائص مرنة من الممكن أن تكون مفيدة غالبًا لأي تطبيق. فيما يلي نسرد بعضًا من مميزات وعيوب هذه التقنية. مميزات التخزين الكتلي: التخزين الكتلي شائع ومألوف، حيث أن المستخدمين والبرمجيات يفهمونه ويستطيعون التعامل مع ملفاته وأنظمته بشكل واسع. الأجهزة الكتلية مدعومة جيدًا. كل لغات البرمجة تستطيع قراءة وكتابة الملفات منها. صلاحيات وأذونات ملفات النظام في الأجهزة الكتلية مألوفة ومفهومة بشكل جيد. أجهزة التخزين الكتلي لديها وقت استجابة منخفض في عمليات الإدخال والإخراج، مما يجعلها مناسبة لقواعد البيانات. عيوب التخزين الكتلي: التخزين مرتبط بخادم واحد في نفس الوقت. تحتوي كتلة التخزين وملفات النظام على بيانات وصفية (metadata) قليلة عن المعلومات التي تُخزنها مثل تاريخ الإنشاء، المستخدم الذي تعود له البيانات وحجم هذه البيانات. أي معلومات إضافية عما تُخزنه وحدة التخزين الكتلي يجب أن يتم التعامل معها على مستوى التطبيق أو قاعدة البيانات مما يؤدي إلى زيادة الأعباء على المطور لمتابعة هذه المعلومات. يجب عليك أن تدفع مقابل حجم التخزين الذي حجزته حتى لو لم تقم بالاستفادة منه أو استخدامه. تستطيع أن تصل لخدمة التخزين الكتلي عبر خادومٍ واحد يعمل فقط. التخزين الكتلي يحتاج إلى اعدادات تنصيب وعمل أكثر (اختيار ملفات النظام، الأذونات، الإصدارات، النسخ الاحتياطية...وغيرها) مقارنة بالتخزين الكائني. بسبب سرعة عمليات الإدخال والإخراج في التخزين الكتلي ، فإنه يُعتبر خيارًا أفضل لتخزين البيانات في قواعد البيانات العادية. بالإضافة لذلك، فإن العديد من الأنظمة القديمة تتطلب وجود ملفات نظام عادية للتخزين مما يجعل التخزين الكتلي هو الحل في هذه الحالة. إذا لم يتوفر لدى مزود الخدمات السحابية خدمة التخزين الكتلي، تستطيع أن تقوم بتشغيل الخدمة الخاصة بك بنفسك باستخدام OpenStack Cinder، Ceph، أو خدمة iSCSI المُضمنة مع العديد من أجهزة NAS. ما هو التخزين الكائني؟ في عالم الحوسبة السحابية الحديث، يُعرف التخزين الكائني بأنه تخزين واسترجاع البيانات غير المُرتبة وفق بنية معينة (Unstructured) عبر استخدام الواجهة البرمجية ل HTTP. فبدلًا من تقسيم الملفات إلى كُتل متعددة وحفظها باستخدام نظام الملفات على وحدة التخزين، يتم التعامل مع الملفات ككائنات وتُحفظ على الشبكة. قد تكون هذه الكائنات عبارة عن صورة، سجلات، ملفات HTML أو أية كائنات ثنائية كبيرة بذاتها. تكون هذه الكائنات غير مرتبة وفق بنية معينة لأنها لا تحتاج لاتباع مُخطط أو تنسيق محدد. أصبح التخزين الكائني معروفًا بسبب قدرته الكبيرة على تبسيط تجربة المطور في بناء وتطوير خدمات التخزين، حيث تم تطوير مكتبات تدعم بناء الواجهات البرمجية (التي تحتوي طلبات (HTTP في أغلب لغات البرمجة. حفظ ملف ثنائي كبير أصبح أمرًا سهلًا باستخدام طلب HTTP PUT، وكذلك استرجاع الملف وبياناته الوصفية يتم عبر طلب GET عادي. علاوة على ذلك، فأغلب خدمات التخزين الكائني تستطيع مشاركة هذه الملفات مع المستخدمين الآخرين دون الحاجة لإعدادات خاصة على الخادم المُستضيف. بالإضافة لما سبق، لن تَدفع مقابل خدمة التخزين الكائني إلا مقابل المساحة التي تَستخدمها (بعض الخدمات تُدفع مقابل كل طلب HTTP أو حسب استهلاك النقل عبر النطاق) وهذا الأمر يُعد نعمةً لبعض المطورين الذين يحصلون على خدمة استضافة وتخزين عالمية مقابل تكلفة تتلاءم مع حجم الاستخدام. التخزين الكائني ليس الحل الجيد لكل الحالات. لنلقي نظرة على مميزات وعيوب هذه النوع. مميزات التخزين الكائني: واجهة برمجية بسيطة عبر HTTP تدعم أغلب المستخدمين بغض النظر عن نظام التشغيل المستخدم أو لغة البرمجة. تكلفة التخزين تُحدد مقابل ما يتم استخدامه من مساحة وليس ما يتم حجزه. لن تحتاج لحجز خادوم كامل للحصول على خدمة التخزين الكائني لملفاتك الساكنة. بعض مزودي خدمة التخزين الكائني تُقدم خاصية الدمج CDN المُضمنة، والتي تتيح تخبئة ملفاتك حتى يكون تنزيلها أسرع للمستخدمين. خاصية الأَصْدَرَة (Versioning) التي تتيح لك استرجاع النسخ القديمة من ملفاتك واستعادتها بعد التعديل عليها بشكل خاطئ. تتكيف خدمات التخزين الكائني مع احتياجات الاستخدام بدءًا من الاستخدام البسيط وحتى حالات الاستخدام المكثف دون أن يحتاج المطور لزيادة المصادر أو إعادة الهيكلة لمعالجة الحمل المطلوب. باستخدام خدمات التخزين الكائني لن تحتاج لمتابعة وإدارة وحدات التخزين أو أنظمة RAID لأنها من مسئولية مزود الخدمة. تستطيع حفظ بيانات وصفية بجانب البيانات الأصلية وذلك يُبسط لك هيكلة التطبيق الذي تعمل عليه. عيوب التخزين الكائني: لا تستطيع أن تستضيف قاعدة بيانات عادية على خدمة التخزين الكائني بسبب وقت الاستجابة العالي واللازم لقاعدة البيانات. باستخدام التخزين الكائني لا تستطيع التعديل على جزء من الكائن الذي تحفظه، حيث عليك قراءة أو كتابة الكائن كله في العملية الواحدة وهذا له آثار مترتبة على الأداء. فمثلًا، باستخدام نظام الملفات تستطيع بسهولة أن تُضيف سطر في نهاية ملف سجلات، ولكن في نظام التخزين الكائني يجب عليك قراءة الملف كاملا ثم التعديل عليه ثم إعادة كتابته وحفظه مرة أخرى، وهذا الأمر يجعل من التخزين الكائني خيارًا غير مثالي في حفظ البيانات التي تتغير بشكل مستمر. لا تستطع نُظم التشغيل تعيين كائن كمحرك أقراص بشكل سهل. يوجد بعض العملاء والمحولات التي تساعد في تنفيذ هذا الأمر، ولكن بشكل عام، استخدام الكائن وتصفحه ليس متاحًا بسهولة كما هو متاح لدى التنقل خلال المجلدات في نظام الملفات. بسبب هذه الخصائص، التخزين الكائني مفيد في استضافة الملفات الساكنة، حفظ محتوى المستخدم المتمثل مثلًا في الصور ولقطات الفيديو، حفظ ملفات النسخ الاحتياطي والسجلات. يوجد بعض حلول التخزين الكائني التي تتيح لك حفظ ملفاتك وبياناتك دون القلق على كيفية إدارة الأقراص أو خيارات التوسع. تستطيع مثلا أن تُجرب Minio، وهو خادوم مشهور مُطَوَّرْ باستخدام لغة Go ويقدم خدمة التخزين الكائني، أو تستطيع تجربة Ceph أو OpenStack Swift. خاتمة اختيار طريقة التخزين قد يكون قرارًا معقدًا للمطورين. ناقشنا مزايا وعيوب كلًا من التخزين الكتلي والتخزين الكائني. على الأرجح أن أي تطبيق معقد وذو كفاءة سيحتاج لاستخدام كلا النوعين في التخزين لتلبية كافة الاحتياجات اللازمة للعمل. ترجمة -وبتصرّف- للمقال Object Storage vs. Block Storage Services لصاحبه Brian Boucheron
  12. تتكون المصفوفة في الجافا سكريبت من قائمة عناصر، وتحتوي الجافا سكريبت على العديد من الوظائف المرفقة والتي تعمل على المصفوفات. الوظائف التي تقوم بالتعديل عل المصفوفة الأصلية تُعرف بتوابع التعديل (Mutator Methods)، والوظائف التي تعيد قيمة جديدة أو شكل آخر تُعرف بتوابع الوصول (Accessor Methods). للاستفادة أكثر من هذا المقال، يجب أن يكون لديك معرفة مسبقة بكيفية إنشاء المصفوفات، فهرستها، التعديل عليها والمرور على عناصرها بواسطة حلقة التكرار. تستطيع مراجعة درس فهم المصفوفات في الجافا سكريبت لأخذ فكرة عما سبق. المصفوفات تتشابه مع النصوص من حيث أن كلاهما يتكون من مجموعة من العناصر التي يمكن الوصول لها عبر رقم الفهرس. على الرغم من ذلك، من الأهمية أن نتذكر أن النصوص ثابتة وغير قابلة للتعديل (Immutable). ولكن على الجانب الاّخر، فإن المصفوفات غير ثابتة (Mutable)، ونستطيع التعديل عليها بشكل مباشر. في هذا المقال سوف نشرح عمليات إضافة وإزالة العناصر من المصفوفة، عكس المصفوفة، استبدال المصفوفة والتعديل على عناصرها. الوظيفة ()isArray قبل البدء بشرح توابع التعديل، سنتعرض للوظيفة ()isArray والتي تقوم بفحص هل الكائن عبارة عن مصفوفة أم لا. في حالة كان الكائن الذي نقوم بفحصه من نوع مصفوفة، فإن الوظيفة ستعيد القيمة المنطقية true، وفي حالة لم يكن مصفوفة، فإن الوظيفة ستعيد القيمة المنطقية false. let fish = [ "piranha", "barracuda", "koi", "eel" ]; // Test if fish variable is an array Array.isArray(fish); Output True الوظيفة ()isArray مفيدة بسبب أن العملية typeof التي تُستخدم عادة في فحص هذه الحالات ستعيد لنا القيمة object عند استخدامها مع المصفوفة، ومن المهم في بعض الأحيان معرفة هل الكائن مصفوفة أم لا. لاحظ أن الوظيفة ()isArray تُكتب بطريقة مختلفة عن أغلب وظائف المصفوفات، حيث يتم تمرير الكائن الذي يمثل المصفوفة كمُعطى للوظيفة. بعد أن تعرفنا على الوظيفة التي تساعدنا في فحص هل الكائن الذي نتعامل معه مصفوفة أم لا، سنبدأ بشرح وظائف توابع التعديل. الوظيفة ()pop أول وظيفة سنتناولها في الشرح هي وظيفة ()pop، التي تُزيل العنصر الأخير من نهاية مصفوفة. لنفترض أنه لدينا مصفوفة باسم fish تحتوي على أنواع بعض الأسماك: let fish = [ "piranha", "barracuda", "koi", "eel" ]; عند استدعاء الوظيفة ()pop سيتم إزالة اخر عنصر في المصفوفة، والذي سيكون العنصر الذي يساوي القيمة النصية “eel” : // Use pop method to remove an item from the end of an array fish.pop(); نقوم بطباعة محتوى المصفوفة لنتأكد من أنها أصبحت لا تحتوي القيمة المحذوفة: fish; Output [ 'piranha', 'barracuda', 'koi' ] بذلك نكون قد أزلنا العنصر “eel” من المصفوفة بنجاح. الوظيفة ()pop لا تأخذ أي معاملات أخرى. الوظيفة ()shift الوظيفة ()shift هي وظيفة أخرى من توابع التعديل وتقوم بإزالة العنصر الأول من المصفوفة. لنفترض وجود المصفوفة fish بالعناصر التالية: let fish = [ "piranha", "barracuda", "koi", "eel" ]; نستخدم الوظيفة ()shift لإزالة العنصر الأول “piranha” والموجود في الفهرس رقم 0، وكذلك سيتم إزاحة كافة عناصر المصفوفة بمقدار فهرس واحد للأسفل. // Use shift method to remove an item from the beginning of an array fish.shift(); fish; Output [ 'barracuda', 'koi', 'eel' ] في المثال السابق، تم إزالة العنصر الأول وإجراء عملية الإزاحة لكافة العناصر الباقية، لهذا السبب، وبشكل عام، فإنه يُفضل أن يتم استخدام الوظيفة ()pop قدر المستطاع لإزالة العناصر من المصفوفة لعدم وجود عملية إزاحة العناصر عند استخدامها. الوظيفة ()push الوظيفة ()push تعمل على إضافة عنصر جديد أو عدة عناصر جديدة في نهاية المصفوفة. let fish = [ "piranha", "barracuda", "koi", "eel" ]; لإضافة عنصر جديد، نمرر العنصر للوظيفة كمُعامل: // Use push method to add an item to the end of an array fish.push("swordfish"); fish; Output [ 'piranha', 'barracuda', 'koi', 'eel', 'swordfish' ] من الممكن أيضًا أن نضيف أكثر من عنصر دفعة واحدة لنهاية المصفوفة بالشكل التالي: fish.push("swordfish", "dragonfish") الوظيفة unshift() لإضافة عنصر جديد أو عدة عناصر في بداية المصفوفة، نستخدم الوظيفة ()unshift. let fish = [ "piranha", "barracuda", "koi", "eel" ]; // Use unshift method to add an item to the beginning of an array fish.unshift("shark"); fish; Output [ 'shark', 'piranha', 'barracuda', 'koi', 'eel' ] في المثال السابق، العنصر shark”” تم اضافته في الفهرس رقم 0، مع إزاحة كافة العناصر للإمام. نستطيع إضافة عدة عناصر دفعة واحدة بنفس الطريقة التي استخدمناها مع الوظيفة ()shift وذلك بتمرير العناصر بحيث تكون مفصولة عن بعضها بفاصلة عادية. الوظيفتان ()pop و ()push تؤثران على نهاية المصفوفة، والوظيفتان ()shift و ()unshift تؤثران على بداية المصفوفة. يوجد طريقة سهلة لتذكر هذه المعلومة وهي معرفة أن الوظيفتان ()shift و ()unshift تقومان بعمل إزاحة للعناصر في المصفوفة. الوظيفة ()splice تقوم الوظيفة ()splice بإضافة أو إزالة عنصر من أي موقع في المصفوفة. الوظيفة تقوم إما بالإضافة أو الحذف كلٌ على حدة، أو الإضافة والحذف بشكل متزامن. تأخذ الوظيفة ()splice ثلاث معاملات، الأول هو الفهرس الذي سنبدأ من عنده العملية، الثاني هو عدد العناصر التي نريد حذفها، الثالث هو العنصر الذي نريد اضافته (اختياري). splice(index number, number of items to remove, items to add) الأمثلة التالية توضح كيفية استخدام الوظيفة ()splice في إضافة وحذف العناصر في المصفوفة. الإضافة باستخدام ()splice إذا قمنا بإعداد المعامل الثاني في الوظيفة ()splice ليأخذ القيمة 0، فإنه لن يتم حذف أي عنصر. بهذه الطريقة، نستطيع أن نضيف عنصر لمصفوفة في أي موقع فيها، وهذه الطريقة تُعتبر أفضل وأقوى من استخدام الوظيفتين ()push و ()unshift واللتان تقومان بالإضافة في نهاية المصفوفة أو بدايتها فقط. let fish = [ "piranha", "barracuda", "koi", "eel" ]; // Splice a new item number into index position 1 fish.splice(1, 0, "manta ray"); fish; Output [ 'piranha', 'manta ray', 'barracuda', 'koi', 'eel' ] النص الجديد “manta ray” تم إضافته للمصفوفة في الفهرس رقم 1. الإزالة باستخدام ()splice إذا تجاهلنا المُعامل الثالث (الاختياري) في الوظيفة ()splice، نستطيع ببساطة إزالة أي عنصر في المصفوفة ومن أي موقع فيها: let fish = [ "piranha", "barracuda", "koi", "eel" ]; // Remove two items, starting at index position 1 fish.splice(1, 2); fish; Output [ 'piranha', 'eel' ] في المثال السابق، قمنا بحذف عنصرين من المصفوفة ابتداء من الفهرس 1. إذا لم نقم بإدخال المعامل الثاني الذي يُمثل عدد العناصر التي نريد حذفها، سيتم حذف جميع عناصر المصفوفة ابتداءً من الفهرس 1 وحتى نهاية المصفوفة. الإضافة والإزالة باستخدام ()splice باستخدام كافة المعاملات للوظيفة ()splice، نستطيع إجراء كلتا عمليتي الإضافة والحذف في نفس الوقت. لتوضيح هذا، لنقم بحذف نفس العناصر السابقة في المثال قبل السابق واضافة العنصر الجديد في الفهرس 1: let fish = [ "piranha", "barracuda", "koi", "eel" ]; // Remove two items and add one fish.splice(1, 2, "manta ray"); fish; Output [ 'piranha', 'manta ray', 'eel' ] الوظيفة ()splice تُعتبر وظيفة قوية في إجراء التعديلات على أي مصفوفة. انتبه أن لا يكون لديك لبس بين الوظيفة ()splice والوظيفة ()slice التي تُعتبر وظيفة من توابع الوصول وتقوم بإنشاء نسخة من جزء من مصفوفة. الوظيفة ()reverse تقوم هذه الوظيفة بعكس ترتيب العناصر في المصفوفة. let fish = [ "piranha", "barracuda", "koi", "eel" ]; باستخدام الوظيفة ()reverse، فإن العنصر الأخير سيكون الأول، والعنصر الأول سيكون اّخر العناصر، ولا تأخذ هذه الوظيفة أي معاملات. // Reverse the fish array fish.reverse(); fish; Output [ 'eel', 'koi', 'barracuda', 'piranha' ] الوظيفة ()fill تقوم الوظيفة ()fill باستبدال جميع عناصر المصفوفة بقيمة ثابتة. let fish = [ "piranha", "barracuda", "koi", "eel" ]; لنفترض وجود المصفوفة fish ولتحتوي على 4 عناصر، باستخدام الوظيفة ()fill سنستبدل جميع العناصر الأربعة بقيمة واحدة: // Replace all values in the array with "shark" fish.fill("shark"); fish; Output [ 'shark', 'shark', 'shark', 'shark' ] نستطيع أن نمرر للوظيفة ()fill معاملين إضافيين وكلاهما اختياري، ويمثلان فهرس البداية الذي نبدأ من عنده عملية الاستبدال وفهرس النهاية الذي ننهي عملية الاستبدال قبله. fish.fill("shark", 1) // > [ 'piranha', 'shark', 'shark', 'shark' ] fish.fill("shark", 1, 3); // > [ 'piranha', 'shark', 'shark', 'eel' ] الوظيفة ()sort الوظيفة ()sort تقوم بترتيب عناصر المصفوفة بناءً على الحرف الأول في العنصر. في حالة وجود أكثر من عنصر بنفس الحرف الأول، يتم الترتيب بناءً على الحرف الثاني وهكذا. بشكل تلقائي تقوم الوظيفة بالترتيب الأبجدي لمصفوفة نصية والتي يكون جميع عناصرها إما uppercase أو lowercase. let fish = [ "piranha", "barracuda", "koi", "eel" ]; // Sort items in array fish.sort(); fish; Output [ 'barracuda', 'eel', 'koi', 'piranha' ] بما أن الوظيفة ()sort تعتمد على الترميز النصي للحرف الأول، فإنها ستُرتب العناصر التي تكون حالتها uppercase قبل العناصر التي حالتها lowercase. انظر للمثال التالي: let fish = [ "piranha", "barracuda", "Koi", "eel" ]; fish.sort(); fish; Output [ 'Koi', 'barracuda', 'eel', 'piranha' ] الأرقام تأتي قبل الأحرف بغض النظر عن حالتها في ترتيب المصفوفة. انظر للمثال التالي: let fish = [ "piranha", "barracuda", "Koi", "1 eel" ]; fish.sort(); Output [ '1 eel', 'Koi', 'barracuda', 'piranha' ] لن تقوم الوظيفة بترتيب مصفوفة أعداد حسب قيمة الأعداد فيها (الأصغر ثم الأكبر)، ولكنها ستقوم بفحص الرقم الأول في كل عدد ويتم الترتيب بناءً عليه. let numbers = [ 42, 23, 16, 15, 4, 8 ]; numbers.sort(); Output [ 15, 16, 23, 4, 42, 8 ] لترتيب الأعداد في مصفوفة أعداد بطريقة سليمة وحسب قيمة الأعداد (من الأصغر إلى الأكبر)، نستطيع إنشاء وظيفة “مقارنة” ونمررها كمعامل للوظيفة ()sort: // Function to sort numbers by size const sortNumerically = (a, b) => { return a - b; } numbers.sort(sortNumerically); Output [ 4, 8, 15, 16, 23, 42 ] خاتمة في هذا الدرس، قمنا باستعراض أغلب وظائف توابع التعديل في لغة الجافا سكريبت. الوظائف من هذا النوع تقوم بالتعديل على المصفوفة الأصلية التي تستخدمها، على العكس من وظائف توابع الوصول، وتعلمنا خلال هذا الدرس كيفية إضافة وإزالة العناصر من المصفوفة في بدايتها أو نهايتها، بالإضافة لكيفية ترتيب المصفوفة، عكسها واستبدال عناصرها. لمراجعة أساسيات المصفوفات، راجع درس فهم المصفوفات في الجافا سكريبت. ترجمة -وبتصرّف- للمقال How To Use Array Methods in JavaScript Mutator Methods لصاحبه Tania Rascia حقوق الصورة البارزة محفوظة لـ Freepik
  13. مقدمة تُعتبر المصفوفة في الجافا سكريبت كائن عمومي (global) الغرض منه هو تخزين البيانات، وتحتوي المصفوفة إما على مجموعة من العناصر بنوع بيانات واحد أو أكثر، وقد تكون فارغة. نستخدم الفهارس العددية التي تبدأ من القيمة 0 للوصول إلى عناصر المصفوفة. المصفوفات مفيدة جدًا بما أنها تُخزن عدة قيم في متغير واحد، وهذا الأمر يقلل وينظم الشيفرة البرمجية التي نكتبها ويجعلها أكثر ملائمة للقراءة والصيانة. تستطيع المصفوفة أن تحتوي على أي نوع بيانات، ابتداءً من الأرقام ومرورا بالنصوص والكائنات وغيرها من أنواع البيانات. لتوضيح كيف من الممكن أن تكون المصفوفات مهمة، لنفترض أننا نريد أن نحفظ أسماء المحيطات في متغيرات عدة، بحيث يكون لكل محيط المتغير الخاص به: oceans.js // Assign the five oceans to five variables const ocean1 = "Pacific"; const ocean2 = "Atlantic"; const ocean3 = "Indian"; const ocean4 = "Arctic"; const ocean5 = "Antarctic"; هذه الطريقة مُضجرة جدا، وتُصبح أكثر صعوبة بشكل متسارع في المتابعة والصيانة. باستخدام المصفوفات، نستطيع تبسيط الأمر. oceans.js // Assign the five oceans let oceans = [ "Pacific", "Atlantic", "Indian", "Arctic", "Antarctic", ]; بدلًا من استخدام خمسة متغيرات منفصلة، نستطيع الان أن يكون لدينا متغير واحد يحتوي على جميع العناصر الخمسة. لإنشاء المصفوفة، نستخدم الأقواس المربعة [ ] كما هو واضح في الشيفرة البرمجية السابقة، وللوصول إلى عنصر معين في المصفوفة، نستخدم الفهرس مع المصفوفة بالطريقة التالية: // Print out the first item of the oceans array oceans[0]; Output Pacific في هذا الدرس سنتعلم كيفية بناء المصفوفة، وكيفية الوصول إلى عناصرها، والاضافة إليها وتعديلها والحذف منها، كما سنتعلم كيفية المرور خلال عناصرها باستخدام حلقة التكرار. إنشاء مصفوفة يوجد طريقتان لإنشاء المصفوفة في جافا سكريبت: التعريف اللفظي باستخدام الأقواس المعكوفة. التعريف بواسطة الباني (constructor) باستخدام كلمة new. لنوضح كيفية إنشاء مصفوفة تحتوي على أنواع سمك القرش، وذلك باستخدام التعريف اللفظي بواسطة الأقواس المربعة: sharks.js // Initialize array of shark species with array literal let sharks = [ "Hammerhead", "Great White", "Tiger", ]; الان نُعرف نفس المصفوفة باستخدام الباني وذلك بواسطة الجملة new Array() : sharks.js // Initialize array of shark species with array constructor let sharks = new Array( "Hammerhead", "Great White", "Tiger", ); كلا الطريقتين سوف يُنشئ لنا المصفوفة، ولكن طريقة التعريف اللفظي هي المشهورة والأكثر تفضيلا بما أن التعريف باستخدام الباني قد يؤدي إلى نتائج غير مستقرة وغير متوقعة وعليك الانتباه في حال صادفتك تلك الطريقة في التعريف أو في حال استخدامك لها. نستطيع طباعة محتويات المصفوفة بكتابة المتغير الخاص بها مباشرة: // Print out the entire sharks array sharks; Output [ 'Hammerhead', 'Great White', 'Tiger' ] تُستخدم المصفوفات عادة في تجميع العناصر أو القوائم من نفس نوع البيانات، ولكن من الناحية التقنية، فإن المصفوفات تستطيع أن تحتوي على عناصر من أنواع مختلفة بالإضافة إلى إمكانية أن تحتوي على مصفوفات أخرى: // Initialize array of mixed datatypes let mixedData = [ "String", null, 7, [ "another", "array", ], ]; بعد أن تعلمنا كيفية إنشاء المصفوفة، نستطيع الان التعامل معا بأكثر من طريقة، ولكننا في البداية نحتاج الى فهم كيفية فهرسة المصفوفات (Arrays Indexing). ملاحظة: قد تجد اخر عنصر في المصفوفة ينتهي بفاصلة وأحيانا قد لا تجد هذه الفاصلة. تُعرف هذه الفاصلة بالفاصلة التابعة (Trailing comma)، ومن الشائع ان تكون غير موجودة، ولكن بشكل عام أصبح من الأفضل أن يتم استخدامها في الشيفرة البرمجية بسبب أنها تجعل الاختلافات بين الإصدارات (في عملية إدارة الإصدارات Versions Control) أكثر وضوحا وتسهل من إضافة وإزالة عناصر المصفوفة دون أخطاء. لاحظ أن الفاصلة التابعة غير مسموح بها في ملفات JSON. فهرسة المصفوفات إذا تعاملت مسبقاً مع النصوص والفهرسة في الجافا سكريبت، ستكون مُلمًا بمفهوم فهرسة المصفوفات، حيث أن النص يُعتبر شبيهًا بالمصفوفة. لا تحتوي المصفوفات على عناصر مزدوجة على شكل اسم/قيمة، وبدلا من ذلك، فإن المصفوفات تُفهرس بقيم عددية تبدأ من القيمة 0. المثال التالي ينشئ مصفوفة باسم seaCreatures: seacreatures.js let seaCreatures = [ "octopus", "squid", "shark", "seahorse", "starfish", ]; الجدول التالي يُفصل كيف يتم فهرسة كل عنصر في المصفوفة بقيمة عددية ابتداءً من 0: octopus squid shark seahorse starfish 0 1 2 3 4 العنصر الأول في المصفوفة هو octopus ومُفهرس في الموقع 0 من المصفوفة، والعنصر الأخير هو starfish ومُفهرس في الموقع 4. تبدأ الفهرسة من 0، وهذا يتضارب مع طبيعتنا الفطرية ببدء العد من القيمة 1، لذلك نحتاج لأخذ الاحتياط وأن نتذكر هذه النقطة دائما حتى تصبح طبيعية. نستطيع أن نحصل على عدد العناصر في المصفوفة باستخدام الخاصية length: seaCreatures.length; Output 5 على الرغم من أن الفهارس الخاصة بالمصفوفة seaCreatuers تبدأ من 0 إلى 4، فإن الخاصية length سوف تُرجع العدد الفعلي للعناصر الموجودة في المصفوفة. إذا أردنا معرفة رقم الفهرس لعنصر معين في المصفوفة، وليكن مثلا seahorse، نستطيع أن نستخدم لذلك الوظيفة indexOf() : seaCreatures.indexOf("seahorse"); Output 3 إذا لم تحتوي المصفوفة على العنصر الذي نريده، فلن نحصل على رقم فهرس لعنصر غير موجود، وفي هذه الحالة، فإن الوظيفة سترجع لنا القيمة -1 كما في المثال التالي: seaCreatures.indexOf("cuttlefish"); Output -1 بواسطة أرقام الفهارس المرتبطة بعناصر المصفوفة، فإنه لدينا القدرة على الوصول لكل عنصر بشكل منفرد بهدف العمل على هذا العنصر والتعامل معه. الوصول لعناصر المصفوفة يتم الوصول لعنصر في مصفوفة جافا سكريبت بواسطة الإشارة لرقم الفهرس للعنصر بين قوسين معكوفين: seaCreatures[1]; Output squid نعلم أن الرقم 0 سيعيد لنا دائما العنصر الأول في المصفوفة. كذلك نستطيع إيجاد العنصر الأخير في المصفوفة بواسطة إجراء عملية طرح قيمة 1 من قيمة الخاصية length للمصفوفة، والإشارة لناتج هذه العملية كرقم فهرس للعنصر الأخير كما هو موضح في المثال التالي: const lastIndex = seaCreatures.length - 1; seaCreatures[lastIndex]; Output starfish محاولة الوصول لعنصر غير موجود سيعيد لنا undefined: seaCreatures[10]; Output undefined للوصول لعنصر مصفوفة متداخلة (مصفوفة داخل مصفوفة)، فعلينا إضافة فهرس اخر يعود للمصفوفة الداخلية: let nestedArray = [ [ "salmon", "halibut", ], [ "coral", "reef", ] ]; nestedArray[1][0]; Output coral في المثال السابق، قمنا بالوصول للعنصر coral بالإشارة لرقم الفهرس الذي يحتوي المصفوفة الداخلية وهو 1، ثم أشرنا للفهرس الذي يحتوي على العنصر في المصفوفة الداخلية وهو 0. إضافة عنصر لمصفوفة في المتغير seaCreatuers يوجد لدينا 5 عناصر بأرقام فهراس تبدأ من 0 الى 4. إذا أردنا أن نُضيف عنصر جديد لهذه المصفوفة، فيمكننا أن نقوم بذلك بإعطاء قيمة للفهرس التالي الذي يلي اخر فهرس: seaCreatures[5] = "whale"; seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale' ] إذا قمنا بإضافة عنصر وتجاهلنا قيمة الفهرس التالي ووضعنا بدلا منه فهرس بقيمة 7 مثلا، فإن ذلك يؤدي لإضافة عنصر غير مُعرف (undefined) للمصفوفة كما في المثال التالي: seaCreatures[7] = "pufferfish"; seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', , 'pufferfish' ] هذه المشكلة نستطيع تجنبها باستخدام الوظيفة push() والتي تقوم بإضافة العنصر الجديد في نهاية المصفوفة: // Append lobster to the end of the seaCreatures array seaCreatures.push("lobster"); seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', , 'whale', 'pufferfish', 'lobster' ] على العكس تماما من الوظيفة push()، فإن الوظيفة unshift() تقوم بإضافة العنصر في بداية المصفوفة: // Append dragonfish to the beginning of the seaCreatures array seaCreatures.unshift("dragonfish"); seaCreatures; Output [ 'dragonfish', 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', , 'pufferfish', 'lobster' ] باستخدام الوظيفتين السابقتين، ستكون لديك المقدرة على إضافة عناصر جديدة للمصفوفة إما في بدايتها، أو نهايتها. إزالة عنصر من مصفوفة لإزالة عنصر معين من مصفوفة، نستخدم الوظيفة splice(). في المصفوفة seaCreatuers قمنا بإضافة عنصر غير مُعرف وليس له قيمة، ولإزالته نقوم بالتالي: seaCreatures.splice(7, 1); seaCreatures; Output [ 'dragonfish', 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish', 'lobster' ] في الوظيفة splice()، المُعامل الأول يشير لرقم الفهرس الذي سنبدأ بالإزالة من عنده (في هذه الحالة 7)، والمُعامل الثاني يشير لعدد العناصر التي نرغب بإزالتها (في حالتنا سيكون 1 حيث أننا نرغب بإزالة عنصر واحد). الوظيفة splice() ستؤثر على المتغير الأصلي. لذلك، إذا أردنا أن نحافظ على المصفوفة الأصلية دون تغيير، نستخدم الوظيفة slice() ونعطي القيمة الناتجة عنها لمتغير جديد. let newArray = slice(7, 1); الوظيفة pop() ستزيل العنصر الأخير من المصفوفة: // Remove the last item from the seaCreatures array seaCreatures.pop(); seaCreatures; Output [ 'dragonfish', 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish' ] العنصر lobster أُزيل من المصفوفة لأنه العنصر الأخير، ولإزالة العنصر الأول في المصفوفة، نستخدم الوظيفة shift(): // Remove the first item from the seaCreatures array seaCreatures.shift(); seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish' ] باستخدام الوظيفتين pop() و shift() نستطيع إزالة العناصر من بداية المصفوفة أو نهايتها. يُفضل استخدام الوظيفة pop() قدر الإمكان، حيث أن باقي العناصر في المصفوفة تبقى في مواقعها دون تغيير. تعديل العناصر في المصفوفة نستطيع تغيير أي قيمة عنصر في المصفوفة وذلك بإعطاء القيمة الجديدة للعنصر باستخدام عملية المساواة، كما نفعل تماما عند التعامل مع المتغيرات العادية: // Assign manatee to the first item in the seaCreatures array seaCreatures[0] = "manatee"; seaCreatures; Output [ 'manatee', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish' ] طريقة أخرى لتغيير قيمة العنصر باستخدام الوظيفة splice() وذلك بإضافة مُعامل جديد. فمثلا، إذا أردنا تغيير قيمة العنصر seahorse والذي يقع في الفهرس 3، نستطيع إزالته وإضافة قيمة جديدة بدلا منه: // Replace seahorse with sea lion using splice method seaCreatures.splice(3, 1, "sea lion"); seaCreatures(); Output [ 'manatee', 'squid', 'shark', 'sea lion', 'starfish', 'whale', 'pufferfish' ] في المثال السابق، قمنا بإزالة العنصر seahorse من المصفوفة، ووضعنا بدلا منه القيمة sea lion في نفس الفهرس 3. حلقة التكرار خلال المصفوفة نستطيع المرور على عناصر المصفوفة من خلال حلقة تكرار for وذلك بالاستفادة من خاصية length. في المثال التالي، نُنشئ مصفوفة باسم shellfish ونطبع رقم كل فهرس فيها بالإضافة إلى قيمة العنصر المرتبط بالفهرس: // Create an array of shellfish species let shellfish = [ "oyster", "shrimp", "clam", "mussel", ]; // Loop through the length of the array for (let i = 0; i < shellfish.length; i++) { console.log(i, shellfish[i]); } Output 0 'oyster' 1 'shrimp' 2 'clam' 3 'mussel' نستطيع أيضا استخدام حلقة التكرار for…of وهي خاصية جديدة في الجافا سكريبت: // Create an array of aquatic mammals let mammals = [ "dolphin", "whale", "manatee", ]; // Loop through each mammal for (let mammal of mammals) { console.log(mammal); } Output dolphin whale manatee حلقة التكرار for…of لا تقوم باستخدام رقم الفهرس للعناصر في المصفوفة، ولكنها بشكل عام طريقة أبسط وأكثر اختصارا للمرور على المصفوفة من خلال حلقة التكرار. استخدام حلقات التكرار مفيد بشكل كبير في طباعة قيم عناصر المصفوفة وهو يشبه عرض العناصر من قاعدة بيانات خلال موقع الكتروني. خاتمة تُعتبر المصفوفات جزء أساسي ومهم في برمجة الجافا سكريبت. في هذا الدرس تعلمنا كيفية إنشاء المصفوفة، وكيفية فهرستها، وتعلمنا إجراء بعض العمليات المهمة على المصفوفات مثل إزالة العناصر والتعديل عليها. وكذلك تعلمنا طريقتين للمرور على عناصر المصفوفة من خلال حلقات التكرار والتي تهدف لإجراء عمليات على عناصر المصفوفة مثل طباعة محتوياتها وطباعة أرقام الفهارس. ترجمة -وبتصرّف- للمقال Understanding Arrays in JavaScript لصاحبه Tania Rascia حقوق الصورة البارزة محفوظة لـ Freepik
  14. تعتمد صفحات الويب على HTML التي تُحدد محتوى الصفحة.تعدّ CSS لغة منفصلة عن HTML ودورها هو تحديد الشكل والمظهر الخاص بصفحة الويب. الشفرة الخاصّة بـ CSS عبارة عن قواعد ساكنة. كل قاعدة تأخذ مُحدِدًا Selector أو أكثر، وتُرجع قيم لمجموعة من الخصائص الشكلية. تُطبَّق هذه الخصائص بعد ذلك على عناصر صفحة الويب المشار إليها بواسطة المحددات. ملاحظة: لتعلم CSS بطريقة صحيحة، ولأن مخرجات هذه اللغة عبارة عن نتائج مرئية، يجب عليك ممارسة كل ما تتعلمه وننصحك بتطبيقه على موقع dabblet. الهدف الرئيسي من هذا المقال التركيز على كيفية الكتابة الصحيحة مع بعض النصائح. سنتناول في هذا المقال العناوين التالية: التعليقات. المحددات. الخصائص. طريقة استخدام CSS في الصفحة. الأولوية أم التتالي. استعلامات الميديا. التوافقية. التعليقات توجد طريقة واحدة لكتابة التعليقات في ملف CSS وهي كتابة التعليقات بين الرمزين /* */. /* التعليقات تُتكتب هنا ولا يوجد نمط لكتابة التعليق في سطر واحد سوى هذه الطريقة */ المحددات يُستخدم المحدد في استهداف عنصر في صفحة، ويُكتَب بالطريقة التالية: selector { property: value; /* خصائص أخرى*/ } لنفترض وجود العنصر التالي من نوع div في صحة ويب: <div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' /> تستطيع تطبيق قاعدة CSS على هذا العنصر باستخدام أحد أسماء الأصناف Classes التي ينتمي إليها في الصفحة: .class1 { } أو باستخدام جميع أسماء الأصناف المطبَّقة عليه: .class1.class2 { } أو باستخدام نوع العنصر: div { } أو باستخدام الرقم الخاص بالعنصر: #anID { } نستطيع تحدد العنصر من الصفحة في حال وجود صفة Attribute باسم معين: [attr] { font-size:smaller; } أو في حالة وجود صفة بقيمة معينة: [attr='value'] { font-size:smaller; } في حالة وجود صفة معينة في عنصر، ونريد تطبيق قاعدة على هذا العنصر بشرط وجود قيمة تبدأ منها الصفة نستخدم الطريقة التالية: [attr^='val'] { font-size:smaller; } أما إن كان الشرط يتعلّق بقيمة معينة تنتهي بها الصفة: [attr$='ue'] { font-size:smaller; } نستطيع تحديد العنصر في حالة احتواء الصفة على قيمة معينة ضمن قائمة قيم منفصلة عن بعضها بمسافة فارغة (يوافق الشرط أدناه العناصر التي لديها صفة otherAttr تساوي “foo” أو “foo bar” أو “foo bar far” …إلخ): [otherAttr~='foo'] { } أو تحديد العنصر في حالة احتواء الصفة على قيمة معينة ضمن قائمة قيم منفصلة عن بعضها برمز – كما في المثال التالي: [otherAttr|='en'] { font-size:smaller; } نستطيع جمع أكثر من مُحدد ببعضها للحصول على مُحدد مُركز كما في المثال التالي: div.some-class[attr$='ue'] { } من الممكن أيضا أن تقوم بتحديد عنصر يكون تابعا (ابن) لعنصر آخر: div.some-parent > .class-name { } في المثال السابق، يكون العنصر الابن على مستوى واحد أسفل من العنصر الأب. تستطيع أن تُحدد عنصر من سلالة عنصرآأخر (الأب)، وهذا يعني من أي مستوى أسفل من مستوى العنصر الأب (ليس شرطا أن يكون مستوى واحد أقل): div.some-parent .class-name { } يختلف المُحدد التالي عن المُحدد السابق لوجود مسافة فاصلة بين الأسماء: div.some-parent.class-name { } نستطيع تحديد العنصر بناءً على عنصر آخر مجاور له باستخدام الطريقة التالية: .i-am-just-before + .this-element { } أو بناءً على أي عنصر يسبق العنصر الذي نريده: .i-am-any-element-before ~ .this-element { } توجد بعض المُحددات تسمى الأصناف الزائفة pseudo classes تطبَّق على العنصر عندما يكون بحالة محددة، فمثلا، نستطيع تحديد عنصر عندما يمر عليه المؤشر: selector:hover { } أو رابط تمت زيارته: selector:visited { } أو لم تتم زيارته: selected:link { } أو عنصر في حالة التركيز: selected:focus { } لتحديد أول عنصر تابع لعنصر: selector:first-child {} لتحديد آخر عنصر تابع لعنصر: selector:last-child {} نستطيع تنسيق أجزاء محددة من العنصر باستخدام العناصر الزائدة Pseudo elements، فمثلا، نستخدم before لإضافة محتوى قبل محتوى عنصر معين: selector::before {} وafter لإضافة محتوى بعد محتوى عنصر معين: selector::after {} في أماكن معينة، يُستخدم رمز * كحرف “بدل” لاختيار كافة العناصر. * { } /* كل العناصر */ .parent * { } /* كل التابعين */ .parent > * { } /* كل الأبناء */ الخصائص selector { وحدات الطول إما مطلقة أو نسبية. الوحدات النسبية: width: 50%; /* نسبة من عرض العنصر الأب */ font-size: 2em; /* مضاعفة حجم الخط الخاص بالعنصر نفسه*/ font-size: 2rem; /* مضاعفة حجم الخط حسب حجم الخط الخاص بالعنصر الأب */ font-size: 2vw; /* مضاعفة حجم الخط بالنسبة ل 1% من عرض المساحة المرئية للمستخدم*/ font-size: 2vh; /* من الارتفاع*/ font-size: 2vmin; /* مضاعفة حجم الخط لأصغر قيمة من الارتفاع أو العرض*/ font-size: 2vmax; /* لاكبر قيمة */ القيم المطلقة: width: 200px; /* بكسل */ font-size: 20pt; /* نقطة */ width: 5cm; /* سنتميتر */ min-width: 50mm; /* مليميتر */ max-width: 5in; /* إنش */ الألوان: color: #F6E; /* صيغة سداسية قصيرة */ color: #FF66EE; /* صيغة سداسية طويلة */ color: tomato; /* حسب الاسم */ color: rgb(255, 255, 255); /* كقيم rgb */ color: rgb(10%, 20%, 50%); /* كنسبة rgb */ color: rgba(255, 0, 0, 0.3); /* كقيم rgba */ color: transparent; /* الشفافية صفر*/ color: hsl(0, 100%, 50%); /* كنسب hsl */ color: hsla(0, 100%, 50%, 0.3); /* كنسب hsla */ الحدود: border-width:5px; border-style:solid; border-color:red; border: 5px solid red; /* اختصار القواعد السابقة في قاعدة واحدة */ border-radius:20px; /* خاصية ابتداء من css3 */ الصور: background-image: url(/img-path/img.jpg); الخطوط: font-family: Arial; إذا كان اسم الخط به مسافات فيجب وضع الاسم بين علامتي تنصيص: font-family: "Courier New"; في نسرُد لائحة من الخطوط وإن لم يجد المتصفح الخط، يستخدم نوع الخط التالي: font-family: "Courier New", Trebuchet, Arial, sans-serif; } طريقة استخدام CSS في الصفحة توجد ثلاث طرق لإجراء عملية تنسيق صفحة الويب وهي كالتالي: 1- تضمين اسم الملف بالامتداد .css داخل العنصر head في بداية صفحة html كالتالي (وهي الطريقة المُوصى بها): <link rel='stylesheet' type='text/css' href='path/to/style.css'> 2- كتابة قواعد css مباشرة في ملف الصفحة: <style> a { color: purple; } </style> 3- تنسيق العنصر بطريقة مباشرة: <div style="border: 1px solid red;"> </div> الأولوية أم التتالي العنصر الواحد في صفحة الويب قد يكون مُستهدفا (محددا) من قبل مجموعة متعددة من المحددات، وقد يكون هناك تعديل أو تحديد لقيمة خاصية تابعة لهذا العنصر من قبل أكثر من مُحدد. في مثل هذه الحالات، فإن قاعدة واحدة سيكون لها الأولوية في التطبيق على هذا العنصر. القواعد التي تمتلك محددات مُفصلة لها أولوية على المحددات ذات التفاصيل الأقل، والقواعد التي تأتي في النهاية تقوم بالتعديل على القواعد التي قبلها (وهذا يعني أنه في حالة تضمين ملفي css وكلاهما يقومان بتحديد عنصر والتعديل على خصائصه، فإن ترتيب ربط الملفات يحكم تنسيق العنصر حسب قاعدة الترتيب المذكورة والتي تُسمى التتالي أو التتابع). استعلامات الوسائط Media queris استعلامات الوسائط هي خاصية بدأت من CSS 3 وتسمح لك بتحديد متى تُطبَّق قواعد CSS، مثلا عند الطباعة، أو عند كثافة وأبعاد شاشة معينين. أمثلة: هذه قاعدة CSS تُطبَّق على كل الأجهزة. h1 { font-size: 2em; color: white; background-color: black; } يعدّل استعلام الوسيط التالي القاعدة السابقة عند الطباعة: @media print { h1 { color: black; background-color: white; } } يجعل استعلام الوسيط التالي حجم الخط أكبر في شاشة بعرض 480 بكسل على الأقل: @media screen and (min-width: 480px) { h1 { font-size: 3em; font-weight: normal; } } تحتوي استعلامات الوسائط على الخصائص التالية: width, height, device-width, device-height, orientation, aspect-ratio, device-aspect-ratio, color,color-index, monochrome, resolution, scan, grid. من الممكن أن يسبق أغلب الخصائص السابقة خاصيتي min- و max-. خاصية الدقة Resolution غير مدعومة على الأجهزة القديمة، وبدلا من ذلك استخدم خاصية device-pixel-ratio. تحاول كثير من أجهزة الجوال والأجهزة اللوحية عرض الصفحة كما لو كانت على سطح المكتب العادي إلا إذا قمت بإضافة الصفة viewport بالشكل التالي: <head> <meta name="viewport" content="width=device-width; initial-scale=1.0"> </head> التوافقية أغلب المميزات والخصائص الموجودة في CSS2 وكثيرا من CSS3 موجودة في كل المتصفحات والأجهزة، ولكن ينصح من باب الممارسة الأفضل أن يتم الفحص قبل استخدام الخاصية الجديدة. ترجمة – بتصرّف – للمقال Learn X in Y minutes Where X=CSS.
  15. وضع Netscape’s Brendan Eich أسس جافا سكريبت سنة 1995. وكان الغرض منها أن تكون لغة ترميز سهلة خاصة بالمواقع ومكملة للجافا في تطبيقات الويب المعقدة، ولكن سهولة دمج جافا سكريبت والدعم الذاتي لها مع المتصفحات جعلها أكثر شيوعًا من لغة الجافا الأصلية في واجهات الويب. لا يقتصر استخدام جافا سكريبت مقتصرة على المتصفحات، ف Node.js مشروع قائم بذاته ويقدم إمكانية بناء تطبيقات إنترنت قائمة بذاتها. صيغة الشفرة البرمجية الخاصة بجافا سكريبت شبيهة بطريقة كتابة لغة C، فإذا كنت قد تعاملت مع لغة البرمجة C قبل ذلك أو جافا، ستكون الكثير من الأساسيات مألوفة لك. على الرغم من ذلك، وعلى الرغم من سهولة الاسم، إلا أن النموذج الكائني في جافا سكريبت مختلف تماماً عن الموجود في الجافا. سنتناول في هذا المقال المواضيع التالية: التعليقات. الأرقام، النصوص والعمليات. المتغيرات، المصفوفات والكائنات. جمل التحكم والمنطق. الدوال، نطاق الوصول و Closures. المشيّدات Constructors والنماذج الأولية Prototypes التعليقات لكتابة تعليق من سطر واحد نبدأ السطر بعلامتي / كما في السطر التالي: // Single-line comments start with two slashes. لكتابة تعليق من أكثر من سطر، نستخدم /* و */ في إحاطة الأسطر التي نريدها كما في الأسطر التالية: /* Multiline comments start with slash-star، and end with star-slash */ تنتهي الجمل في جافا سكريبت بفاصلة منقوطة، ولكن هذا الأمر غير ضروري، حيث يتم إضافة الفاصلة المنقوطة تلقائيا عند وجود سطر جديد وعدم وجود الفاصلة، وهذا الأمر مستثنى في بعض الحالات: doStuff(); بدون فاصلة: doStuff() سنعتمد في هذا الدرس استخدام الفاصلة المنقوطة. الأرقام، النصوص والعمليات تحتوي جافا سكريبت على نوع رقمي واحد (64-bit IEEE 754 double). الأرقام من نوع Double (الأعداد الحقيقة) تحتوي على 52 بت من الأساس العشري، بما يكفي لتخزين الأعداد الصحيحة Integers حتى 9✕10¹⁵ بدقة. 3; // = 3 1.5; // = 1.5 بعض العمليات الحسابية الأساسية: 1 + 1; // = 2 0.1 + 0.2; // = 0.30000000000000004 8 - 1; // = 7 10 * 2; // = 20 35 / 5; // = 7 5 / 2; // = 2.5 10 % 2; // = 0 30 % 4; // = 2 18.5 % 7; // = 4.5 العمليات الثنائية متاحة أيضا، فعند إجراءك لعملية ثنائية، فإن الأعداد العشرية Float يتم تحويله إلى أعداد طبيعية Int حتى 32 بت: 1 << 2; // = 4 ترتيب العمليات يتم بواسطة استخدام الأقواس: (1 + 3) * 2; // = 8 توجد ثلاثة قيم أرقام غير حقيقية كالتالي: Infinity; // ناتجة عن قسمة رقم موجب على صفر -Infinity; // ناتجة عن قسمة رقم سالب على صفر NaN; //تشير إلى قيمة "غير رقم" القيم المنطقية: true; false; يتم استخدام علامة التنصيص المنفردة أو المزدوجة لبناء النصوص: 'abc'; "Hello، world"; لعكس القيمة نستخدم علامة التعجب: !true; // = false !false; // = true لفحص المساواة: 1 === 1; // = true 2 === 1; // = false لفحص عدم المساواة: 1 !== 1; // = false 2 !== 1; // = true عمليات المقارنة: 1 < 10; // = true 1 > 10; // = false 2 <= 2; // = true 2 >= 2; // = true دمج النصوص يتم بواسطة عملية + : "Hello " + "world!"; // = "Hello world!" وعملية الدمج + لا تعمل فقط مع النصوص، بل مع الأرقام أيضا والتراكيب مثل المصفوفات: "1، 2، " + 3; // = "1، 2، 3" "Hello " + ["world"، "!"] // = "Hello world،!" من الممكن مقارنة النصوص: "a" < "b"; // = true لإجراء عملية فحص المساواة باعتبار تحويل أنواع البيانات (في حالة اختلافها) نستخدم عملية = مرتين: "5" == 5; // = true null == undefined; // = true في حالة استخدام = ثلاثة مرات، لا تتم عملية التحويل: "5" === 5; // = false null === undefined; // = false لابد من الانتباه من التحويل التلقائي للنوع تجنبا لبعض الحالات غير المرغوبة: 13 + !0; // 14 "13" + !0; // '13true' نستخدم charAt للوصول لمحرف Character معين في النصوص بتعيين مكانها في سلسلة المحارف: "This is a string".charAt(0); // = 'T' أو نستخدم substring للحصول على أجزاء أكبر من النصوص: "Hello world".substring(0, 5); // = "Hello" length تعتبر خاصية، لذلك لا تستخدم الأقواس في النهاية: "Hello".length; // = 5 نستخدم null للإشارة للفارغ أو غير الموجود، بينما نستخدم undefined للإشارة لقيمة غير منشأة أو غير موجودة حاليا (مثل تعريف متغير وعدم إعطائه قيمة). القيم false، null، undefined، NaN، 0 ،”” كلها قيم خاطئة (تستخدم كقيمة منطقية خطأ) والباقي صحيح. المتغيرات، المصفوفات، والكائنات يتم تعريف المتغيرات باستخدام كلمة var. جافا سكريبت ديناميكية النوع، حيث لا يجب عليك تحديد نوع المتغير عند تعريفه، ولإعطاء قيمة للمتغير نستخدم = كما في المثال التالي: var someVar = 5; عند عدم استخدام كلمة var لن يظهر لك خطأ، ولكن في هذه الحالة فإن المتغير يكون مستواه على نطاق الوصول العام Global scope ولن يكون على المستوى الذي تم تعريفه فقط. someOtherVar = 10; المتغيرات التي لا تأخذ قيمة عند تعريفها تكون بقيمة undefined تلقائيا: var someThirdVar; // = undefined لتعريف أكثر من متغير في نفس السطر نفصل بين المتغيرات بفاصلة عادية: var someFourthVar = 2، someFifthVar = 4; نستطيع اختصار كتابة العمليات الحسابية بالشكل التالي: someVar += 5; // هذا يعادل someVar = someVar + 5; someVar is 10 now someVar *= 10; // someVar = 100 someVar++; // someVar = 101 someVar--; // back = 100 المصفوفات عبارة عن قائمة من القيم المرتبة من أي نوع: var myArray = ["Hello"، 45، true]; نستطيع الوصول لمحتويات المصفوفة باستخدام الأقواس المعكوفة والفهرس. فهرس المصفوفات يبدأ من صفر: myArray[1]; // = 45 المصفوفات غير ثابتة وذات حجم متغير: myArray.push("World"); myArray.length; // = 4 للتعديل أو الإضافة في موقع معين في المصفوفة: myArray[3] = "Hello"; لتعريف قاموس (Hash): var myObj = {key1: "Hello"، key2: "World"}; المفاتيح في القاموس عبارة عن نص، أو مُعرف صحيح، والقيم تأخذ أي نوع: var myObj = {myKey: "myValue"، "my other key": 4}; للوصول إلى قيمة باستخدام مفتاح والأقواس المعكوفة: myObj["my other key"]; // = 4 أو باستخدام صيغة النقطة والمُعِرف الذي يمثل المفتاح: myObj.myKey; // = "myValue" الكائنات في جافا سكريبت غير ثابتة وقابلة للتعديل: myObj.myThirdKey = true; إذا حاولت الوصول لقيمة غير موجودة في القاموس، ستكون النتيجة المرجعة undefined: myObj.myFourthKey; // = undefined جمل التحكم والمنطق جملة if: var count = 1; if (count == 3){ // ستُنفَّذ هذه الشفرةإذا كانت قيمة المتغير تساوي 3 } else if (count == 4){ // ستُنفَّذ هذه الشفرةإذا كانت قيمة المتغير تساوي 4 } else { // ستُنفَّذ هذه الشفرة في حالة عدم تحقق أي شرط سابق } جملة while: while (true){ // جملة تكرار غير منتهية } جملة do تشبه جملة while إلا أنها تُكرَّر مرة واحدة على الأقل: var input; do { input = getInput(); } while (!isValid(input)) جملة For تشبه الموجودة في لغة سي وجافا: for (var i = 0; i < 5; i++){ // ستُنفَّذ هذه الشفرة خمس مرات } توقف جملة التكرار باستخدام break مع تحديد اسم جملة التكرار التي نريد وقفها: outer: for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { if (i == 5 && j ==5) { break outer; } } } تسمح لنا جملة for/in بالمرور على خصائص ومحتويات الكائن. في المثال التالي نقوم بالمرور على محتوى قاموس وحفظ النتيجة في متغير: var description = ""; var person = {fname:"Paul"، lname:"Ken"، age:18}; for (var x in person){ description += person[x] + " "; } // description = 'Paul Ken 18 ' العملية المنطقية and تُمَثَلْ ب && والعملية or تُمَثَلْ ب ||: if (house.size == "big" && house.colour == "blue"){ house.contains = "bear"; } if (colour == "red" || colour == "blue"){ // colour is either red or blue } نستفيد من && و || في تحديد القيم التلقائية كما في المثال التالي: var name = otherName || "default"; جملة switch تفحص المساواة باستخدام ===، استخدم break بعد كل حالة فحص وإلا سيتم تنفيذ حالة case الصحيحة التالية أيضا: grade = 'B'; switch (grade) { case 'A': console.log("Great job"); break; case 'B': console.log("OK job"); break; case 'C': console.log("You can do better"); break; default: console.log("Oy vey"); break; } الدوال، نطاق الوصول وClosures تُعرَّف الدوال في جافا سكريبت باستخدام كلمة function: function myFunction(thing){ return thing.toUpperCase(); } myFunction("foo"); // = "FOO" لابد الانتباه أن تضع القيمة المرجعة في نفس السطر الموجودة به كلمة return، إذا لم يكن كذلك، ستكون النتيجة المرجعة undefined بسبب الإضافة التلقائية للفاصلة المنقوطة عند كل سطر جديد (وقد نوهنا لهذه النقطة في البداية). function myFunction(){ return // الفاصلة المنقوطة مضافة تلقائيا هنا {thisIsAn: 'object literal'} } myFunction(); // = undefined يُتعامل مع الدوال في جافا سكريبت بوصفها كائنات، وهذا يعني أنك تستطيع تمرير الدالة معاملا لدالة أخرى، أو قيمة لمتغير. تُستخدَم الدالة myFunction في معالجة حدث في المثال التالي، حيث سيتم تنفيذها بعد فترة زمنية محددة: function myFunction(){ } // ينتُج عن السطر التالي تنفيذ الدالة أعلاه بعد 5 ثوان setTimeout(myFunction، 5000); ملاحظة: الدالة setTimeout ليست جزءًا من جافا سكريبت، ولكنها مقدمة من قبل المتصفحات و Node.js. وظيفة setInterval أيضا مقدمة من قبل المتصفحات. function myFunction(){ } setInterval(myFunction، 5000); ليس من الشرط تحديد اسم الدالة، ونستطيع كتابة الدالة دون اسم في المكان الذي يتم تمرير قيمتها المُرجعة فيه بالطريقة التالية: setTimeout(function(){ }, 5000); تمتلك جافا سكريبت نطاقاً وظيفياً، حيث لكل دالة نطاقها الخاص، بينما الكتل الأخرى لا تشاركها هذا النطاق. if (true){ var i = 5; } i; // = 5 إن كتبنا الشفرة في المثال السابق داخل دالة فإن قيمة المتغير i تساوي 5 على عكس ما تتوقعه في النطاق الكتلي، بمعنى أن المتغيرات مُشاهدَة ونستطيع الوصول إليها على مستوى الدالة بغض النظر عن مكان تعريفها داخل هذه الدالة. وهذا يشير إلى نمط متعارف عليه يمنع المتغيرات المؤقتة من الظهور في نطاق الوصول العام. وللتوضيح على ما سبق، في المثال التالي، يبقى المتغير temporary داخل نطاق الدالة المُعرف فيها، أما المتغيرات في النطاق العام مثل permanent فنستطيع الوصول إليه باستخدام الكائن العام والمسمى في كل المتصفحات ب window وتكون صيغة الوصول للمتغير هكذا window.permanent. الكائن ذو النطاق العام يختلف اسمه في البيئات التي لا علاقة لها بالمتصفحات مثل Node.js. (function(){ var temporary = 5; window.permanent = 10; })(); temporary; // raises ReferenceError permanent; // = 10 من أقوى خصائص لغة جافا سكريبت وجود ما يسمى بclosures ، حيث إذا كانت دالة مُعرفة داخل دالة أخرى، فإن الدالة الداخلية تمتلك الوصول لكافة المتغيرات الخاصة بالدالة الخارجية حتى بعد خروجها وانتهائها. في المثال التالي، فإن استدعاء الدالة setTimeout سيتم تنفيذها مباشرة بعد استدعاء الدالة الخارجية sayHelloInFiveSeconds والتي ستنتهي مباشرة. ومن ثم سوف يبدأ العد حتى 5 ثوان لاستدعاء الوظيفة الداخلية، وعند انتهاء المدة، وعلى الرغم من خروج وانتهاء الدالة الخارجية، إلا أنه سيتم تنفيذ الداخلية بنجاح وسيتم الوصول للمتغير prompt دون مشاكل. function sayHelloInFiveSeconds(name){ var prompt = "Hello، " + name + "!"; function inner(){ alert(prompt); } setTimeout(inner، 5000); } // سيتم طباعة "مرحبا أدم" بعد 5 ثواني sayHelloInFiveSeconds("Adam"); المشيّدات Constructors والنماذج الأولية Prototypes يمكن للكائنات أن تحتوي على دوال، كما في المثال التالي: var myObj = { myFunc: function(){ return "Hello world!"; } }; myObj.myFunc(); // = "Hello world!" عندما يتم استدعاء دوال معرَّفة في كائن، فإن هذه الدوال تستطيع الوصول للكائن التي عُرِّفت فيه باستخدام كلمة this كما في المثال التالي: myObj = { myString: "Hello world!"، myFunc: function(){ return this.myString; } }; myObj.myFunc(); // = "Hello world!" الدالة myFunc لا تعمل إذا لم يتم استدعاؤها في سياق الكائن الذي تتصل به، لاحظ في المثال التالي: var myFunc = myObj.myFunc; myFunc(); // = undefined نستطيع ربط دالة بكائن والوصول لمتغيرات هذا الكائن بواسطة this على الرغم من أن هذه الدالة لم تُعرَّف مع تعريف بالكائن. var myOtherFunc = function(){ return this.myString.toUpperCase(); } myObj.myOtherFunc = myOtherFunc; myObj.myOtherFunc(); // = "HELLO WORLD!" نستطيع أيضا تحديد سياق الدالة لتنفيذها من خلاله وذلك عن طريق استدعاء الوظيفة باستخدام call او apply. var anotherFunc = function(s){ return this.myString + s; } anotherFunc.call(myObj، " And Hello Moon!"); // = "Hello World! And Hello Moon!" استخدمنا في المثال السابق الدالة call. تؤدّي الدالة apply نفس الغرض ولكننا نمرر لها مصفوفة معاملات، وهذا يفيدنا في حالة التعامل مع دالة تقبل مجموعة من المعاملات. anotherFunc.apply(myObj، [" And Hello Sun!"]); // = "Hello World! And Hello Sun!" Math.min(42، 6، 27); // = 6 Math.min([42، 6، 27]); // = NaN (uh-oh!) Math.min.apply(Math، [42، 6، 27]); // = 6 لاحظ أننا عند استخدام apply و call قمنا بتمرير السياق الذي نريده من خلال myObj. إذا أردنا أن نُثبت السياق الذي نريد تنفيذ الدالة من خلاله، فإننا نستخدم bind عوضا عن ذلك. var boundFunc = anotherFunc.bind(myObj); boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!" نستطيع استخدام bind لتطبيق دالة جزئيا، انظر المثال التالي: var product = function(a، b){ return a * b; } var doubler = product.bind(this، 2); doubler(8); // = 16 عند استدعاء دالة بواسطة الكلمة new فإن كائناً جديداً يتم إنشاؤه وسوف يكون متاحا للدالة بواسطة كلمة this. الدوال التي صُممت للاستدعاء بهذه الطريقة تسمى المشيّدات constructors. var MyConstructor = function(){ this.myNumber = 5; } myNewObj = new MyConstructor(); // = {myNumber: 5} myNewObj.myNumber; // = 5 على خلاف لغات البرمجة الكائنية الأخرى، جافا سكريبت لا تحتوي على مفهوم العيّنة Instance أو “الكائن المتولد من الفئة عند التشغيل”. تُقدم جافا سكريبت المفاهيم الكائنية مثل التوليد والوراثة من خلال مفهوم واحد يسمى النموذج الأولي Prototype. كل كائن في الجافا سكريبت يحتوي على نموذج أولي. عندما تقوم بمحاولة استخدام لخاصية غير موجودة في كائن معين، فإن مفسر جافا سكريبت سوف ينظر في النموذج الأولي للكائن. تجعلك بعض تطبيقات الجافا سكريبت تصل لنموذج الكائن بواسطة الخاصية “proto“. على الرغم من أن هذه الطريقة مفيدة في شرح مفهوم النموذج الأولي، إلا أنها ليست الطريقة المعيارية لذلك، وسوف نشرح الطريقة الصحيحة لهذا الأمر لاحقا. var myObj = { myString: "Hello world!" }; var myPrototype = { meaningOfLife: 42، myFunc: function(){ return this.myString.toLowerCase() } }; myObj.__proto__ = myPrototype; myObj.meaningOfLife; // = 42 myObj.myFunc(); // = "hello world!" في حال لم تكن الخاصية موجودة في النموذج الأولي، فإن المفسر يبحث في نموذج النموذج وهكذا. myPrototype.__proto__ = { myBoolean: true }; myObj.myBoolean; // = true لا يوجد نُسَخْ عند استخدام النموذج، حيث إن كل كائن يقوم بالتأشير للنموذج الخاص به، وهذا يعني أن أي تغيير على النموذج سوف ينعكس في كل مكان آخر. myPrototype.meaningOfLife = 43; myObj.meaningOfLife; // = 43 جملة for/in تسمح بالمرور على خصائص كائن، مرورا بسلسلة النماذج الأولية حتى الوصول إلى نموذج فارغ. for (var x in myObj){ console.log(myObj[x]); } ///prints: // Hello world! // 42 // [Function: myFunc] للمرور على خصائص الكائن دون النموذج، نستخدم وظيفة hasOwnProperty كما في المثال التالي: for (var x in myObj){ if (myObj.hasOwnProperty(x)){ console.log(myObj[x]); } } ///prints: // Hello world! كما ذكرنا سابقا، فإن استخدام “proto” في تعريف نموذج كائن هي طريقة غير معيارية، ولا يوجد طريقة لتغيير نموذج أولي لكائن موجود. على الرغم من ذلك، توجد طريقتان لإنشاء كائن مع نموذج مُعطى. الأولى هي استخدام Object.create: var myObj = Object.create(myPrototype); myObj.meaningOfLife; // = 43 الطريقة الثانية – مضمونة أكثر - باستخدام المشيّدات. تمتلك المشيّدات خاصية تسمى prototype تُحدَّد عند إنشاء كائن جدي باستخدام كلمة new، المثال التالي يشرح هذا الأمر: MyConstructor.prototype = { myNumber: 5، getMyNumber: function(){ return this.myNumber; } }; var myNewObj2 = new MyConstructor(); myNewObj2.getMyNumber(); // = 5 myNewObj2.myNumber = 6 myNewObj2.getMyNumber(); // = 6 توجد لدى أنواع البيانات مثل النصوص والأرقام مشيّدات تقوم بإنشاء كائنات تعادل الكائنات المنشأة بطريقة عادية. عدا أنها ليست متماثلة تماما! var myNumber = 12; var myNumberObj = new Number(12); myNumber == myNumberObj; // = true typeof myNumber; // = 'number' typeof myNumberObj; // = 'object' myNumber === myNumberObj; // = false if (0){ //لن تُنفَّذ هذه الشفرة لأن قيمة الصفر خاطئة } if (new Number(0)){ //سوف تُنفَّذ هذه الشفرة لأن الرقم في الشرط عبارة عن كائن وليس نوع رقم، والكائنات دائما ذات قيمة منطقية صحيحة } الكائنات المغلفة أو العادية تتشارك في النموذج الأولي الخاص بنوعها، فمثلا، نستطيع إضافة خاصية على النموذج الخاص بنوع string بهدف الحصول على الحرف الأول من النص، كما في المثال التالي: String.prototype.firstCharacter = function(){ return this.charAt(0); } "abc".firstCharacter(); // = "a" تُستخدَم الخاصية السابقة غالباً في ما يُعرَف بالملْء المتعدّد Polyfilling والتي تُطَبِقْ مميزات أحدث من جافا سكريبت في مجموعة قديمة من نُسخ جافا سكريبت بهدف استخدام هذه المميزات الحديثة في بيئات قديمة مثل المتصفحات المنتهية تاريخا. ملاحظة: تنفيذ Object.create قد يكون غير متاح في بعض التطبيقات، ولكننا نستطيع استخدام الملْء المتعدّد لتعويض هذا الغياب كالتالي: if (Object.create === undefined){ //في حالة كانت موجودة لا تعدل عليها Object.create = function(proto){ // أنشئ مشيّدًا مؤقتا باستخدام النموذج الأولي المناسب var Constructor = function(){}; Constructor.prototype = proto; return new Constructor(); } } ترجمة – بتصرّف – للمقال Learn X in Y minutes Where X=javascript.