المتغيرات هي هيكل بيانات تعيّن اسمًا تمثيليًا لقيمة. يمكن أن تحتوي على بيانات من أي نوع.
ويُسمى اسم المتغيّر identifier. يجب أن يتّبع المعرّف الصالح. القواعد التالية:
- يمكن أن تحتوي المعرّفات على أحرف يونيكود وعلامات الدولار ($) وشرطة سفلية. الأحرف (_) والأرقام (0-9) وحتى بعض أحرف Unicode.
- لا يمكن أن تحتوي المعرّفات على مسافة بيضاء، لأن المحلل يستخدم مسافة بيضاء
عناصر الإدخال المنفصلة. على سبيل المثال، إذا حاولت استدعاء متغير
my Variable
بدلاً منmyVariable
، يرى المحلل اللغوي معرّفين،my
وVariable
، وتعرض خطأ في البنية ("رمز مميّز غير متوقع: ). يجب أن تبدأ المعرّفات بحرف أو شرطة سفلية (
_
) أو علامة الدولار ($
). ولا يمكن أن تبدأ بأرقام، وذلك لمنع الالتباس بين الأرقام المعرفات:let 1a = true; > Uncaught SyntaxError: Invalid or unexpected token
إذا كانت لغة JavaScript تسمح باستخدام الأرقام في بداية المعرّف، سيسمح ذلك معرفات تتكون من أرقام فقط، مما يتسبب في حدوث تعارض بين الأرقام المستخدمة الأرقام والأرقام المستخدمة كمعرّفات:
let 10 = 20 10 + 5 > ?
"الكلمات المحجوزة" إذا كانت ذات مغزى من الناحية التركيبية، لا يمكن استخدامها كمعرّفات.
لا يمكن أن تحتوي المعرّفات على رموز خاصة (
! . , / \ + - * =
).
ليست ما يلي قواعد صارمة لإنشاء معرّفات، ولكنها أفضل ممارسات المجال التي تجعل صيانة التعليمات البرمجية أسهل. إذا كانت تفاصيل لمشروعك معايير مختلفة، اتبع هذه المعايير بدلاً من ذلك من أجل الاتساق.
باتباع المثال الذي تحدده الطرق والخصائص المضمنة في JavaScript، حالة الجمل (تسمّى أيضًا "حالة الجمل") هي اصطلاح شائع جدًا لوصف المعرفات المكونة من عدة كلمات. حالة الجمل هي ممارسة كتابة حرف كبير في بداية كل كلمة باستثناء الحرف الأول من كل كلمة سهولة القراءة بدون مسافات.
let camelCasedIdentifier = true;
تستخدم بعض المشروعات اصطلاحات تسمية أخرى اعتمادًا على السياق وطبيعة من البيانات. على سبيل المثال، الحرف الأول من فئة تكون عادةً بأحرف كبيرة، لذا فإنّ أسماء الفئات المكوّنة من عدة كلمات غالبًا ما تستخدم صيغة أخرى من الجمل حالة تُعرف عادةً باسم "حالة الجمل العليا" أو حالة Pascal.
class MyClass {
}
يجب أن تصف المعرفات بإيجاز طبيعة البيانات التي تحتوي عليها (إذا كان
على سبيل المثال، currentMonthDays
هو اسم أفضل من theNumberOfDaysInTheCurrentMonth
)
والقراءة بوضوح في لمح البصر (originalValue
أفضل من val
). تشير رسالة الأشكال البيانية
تعمل معرّفات myVariable
المستخدمة في هذه الوحدة في سياق
أمثلة منفصلة، ولكنها قد تكون غير مفيدة للغاية في التعليمات البرمجية الخاصة بالإنتاج لأنها
ولا تقدم أي معلومات حول البيانات التي تحتوي عليها.
يجب ألا تكون المعرّفات محددة جدًا بشأن البيانات التي تحتوي عليها، لأن
يمكن أن تتغير قيمها اعتمادًا على كيفية تصرف النصوص البرمجية على تلك البيانات، أو على
والقرارات التي يتخذها المشرفون في المستقبل. على سبيل المثال، متغير معين في الأصل
قد يلزم تغيير المعرّف miles
إلى قيمة بالكيلومترات لاحقًا في
المشروع، مما يتطلب من المشرفين تغيير أي إشارات إلى هذا المتغير
لتجنب الالتباس المستقبلي. لمنع حدوث ذلك، يمكنك استخدام distance
كمعرّف لك.
بدلاً من ذلك.
ولا تمنح لغة JavaScript أي امتياز أو معنى خاصًا للمعرّفات التي
تبدأ بحروف الشرطة السفلية (_
)، لكنها تُستخدَم عادةً لإظهار
فإن المتغير أو الطريقة أو الخاصية "خاصة"، مما يعني أنه من المفترض أن
للاستخدام ضمن سياق الكائن الذي يحتوي عليه، كما ينبغي عدم
يتم الوصول إليها أو تعديلها خارج هذا السياق. هذا اصطلاح نقل
من لغات برمجة أخرى، ويسبق إضافة لغة البرمجة JavaScript
المواقع الخاصة.
تعريف المتغيّر
هناك عدة طرق لجعل JavaScript على دراية بالمعرّف، وهي عملية
يسمى "الإعلان" متغير. يتم تعريف متغير باستخدام let
أو const
أو var
كلمة رئيسية.
let myVariable;
استخدِم let
أو var
للإعلان عن متغيّر يمكن تغييره في أي وقت. هذه
تخبر الكلمات الرئيسية مترجم JavaScript بأن سلسلة الأحرف
الذي قد يحتوي على قيمة.
عند العمل على قاعدة رموز برمجية حديثة، استخدِم let
بدلاً من var
. لا يزال var
يعمل
في المتصفحات الحديثة، ولكنها تتضمن بعض السلوكيات غير البديهية التي تم تحديدها في
النُسخ الأقدم من JavaScript، ثم تعذر تغييرها لاحقًا إلى
الحفاظ على التوافق مع الأنظمة القديمة. تمت إضافة let
في ES6 لحلّ بعض المشاكل
بتصميم var
.
يتم تهيئة المتغير المُعلَن عنه من خلال تعيين قيمة للمتغير. يمكنك استخدام
علامة يساوي واحدة (=
) لتعيين قيمة لمتغير أو إعادة تعيينها. يمكنك إجراء ما يلي:
هذا كجزء من البيان نفسه الذي يذكر أنه:
let myVariable = 5;
myVariable + myVariable
> 10
يمكنك أيضًا التعريف عن متغيّر باستخدام let
(أو var
) بدون إعداده.
في الحال. إذا فعلت ذلك، فستكون القيمة الأولية للمتغير undefined
حتى
يعينه التعليمة البرمجية قيمة.
let myVariable;
myVariable;
> undefined
myVariable = 5;
myVariable + myVariable
> 10
يختلف المتغيّر الذي يتضمّن قيمة undefined
عن متغيّر غير محدَّد.
الذي لم يتم الإعلان عن معرّفه بعد. الإشارة إلى متغير لم
المعلن عنها إلى خطأ.
myVariable
> Uncaught ReferenceError: myVariable is not defined
let myVariable;
myVariable
> undefined
إن الارتباط بين المعرف بإحدى القيم يسمى عمومًا "ربط".
يُطلق على البنية التي تتّبع الكلمات الرئيسية let
أو var
أو const
اسم
و"قائمة الربط" وتسمح باستخدام تعريفات متغيّرات متعددة مفصولة بفواصل
(تنتهي بالفاصلة المنقوطة المتوقعة). يؤدي هذا إلى إنشاء مقتطفات الرمز التالية
متطابقة وظيفيًا:
let firstVariable,
secondVariable,
thirdVariable;
let firstVariable;
let secondVariable;
let thirdVariable;
لا تستخدم إعادة تحديد قيمة متغيّر let
(أو var
)، لأنّ JavaScript
بالفعل وجود المتغير وهو:
let myVariable = true;
myVariable
> true
myVariable = false;
myVariable
> false
يمكنك إعادة تحديد قيم جديدة للمتغيّرات استنادًا إلى قيمها الحالية:
let myVariable = 10;
myVariable
> 10
myVariable = myVariable * myVariable;
myVariable
> 100
إذا حاولت إعادة تعريف متغيّر باستخدام let
في بيئة إنتاج،
سيظهر لك خطأ في البنية:
let myVariable = true;
let myVariable = false;
> Uncaught SyntaxError: redeclaration of let myVariable
المتصفحات أدوات المطوّرين
الأكثر تساهلاً في إعادة تعريف let
(وclass
)، لذا قد لا
سيظهر لك الخطأ نفسه في وحدة تحكم المطوّرين.
للحفاظ على توافق المتصفِّح القديم، يسمح var
بإعادة التعريف غير الضرورية.
بدون خطأ في أي سياق:
var myVariable = true;
var myVariable = false;
myVariable\
> false
const
استخدِم الكلمة الرئيسية const
للإعلان عن الثابت، وهو نوع من المتغيّرات التي يجب
على الفور، ومن ثم لا يمكن تغييرها. معرّفات الثوابت
اتّباع جميع القواعد نفسها المستخدَمة في المتغيّرات التي تم تعريفها باستخدام let
(وvar
):
const myConstant = true;
myConstant
> true
لا يمكنك الإعلان عن ثابت دون تعيين قيمة له على الفور، لأن
لا يمكن إعادة تعيين الثوابت بعد إنشائها، وبالتالي فإن أي ثوابت غير مهيأة
الثابت سيبقى undefined
إلى الأبد. إذا حاولت الإعلان عن قيمة ثابتة
دون إعداده، ستحصل على خطأ في البنية:
const myConstant;
Uncaught SyntaxError: missing = in const declaration
يمكن أن تؤدي محاولة تغيير قيمة متغير مُعلَن عنه باستخدام const
بالطريقة المُعلَنة
يؤدي تغيير قيمة المتغير المُعلَن عنه مع let
(أو var
) إلى نوع
خطأ:
const myConstant = true;
myConstant = false;
> Uncaught TypeError: invalid assignment to const 'myConstant'
ومع ذلك، عندما يرتبط العدد الثابت بكائن، فإنّ خصائص ذلك يمكن تغيير كائنه.
const constantObject = { "firstvalue" : true };
constantObject
> Object { firstvalue: true }
constantObject.secondvalue = false;
constantObject
> Object { firstvalue: true, secondvalue: false }
يكون الثابت الذي يحتوي على كائن غير قابل للتغيير الإشارة إلى قيمة بيانات قابلة للتغيير وعلى الرغم من أنه لا يمكن تغيير الثابت نفسه، إلا أن خصائص الدالة المشار إليها أي كائن يمكن تعديله أو إضافته إليه أو إزالته:
const constantObject = { "firstvalue" : true };
constantObject = false
> Uncaught TypeError: invalid assignment to const 'constantObject'
عندما لا تتوقع إعادة تعيين متغير، فمن أفضل الممارسات أن تجعله
ثابت. إنّ استخدام "const
" يخبر فريق التطوير أو المشرفين المستقبليين
مشروعك عدم تغيير تلك القيمة، لتجنب كسر الافتراضات التي قد تؤدي إلى
عن كيفية استخدامه - على سبيل المثال، سيتم تحويل المتغير في النهاية
قياسها مقابل نوع بيانات متوقع.
نطاق المتغيّر
نطاق المتغير هو ذلك الجزء من البرنامج النصي حيث يتوفر هذا المتغير.
خارج نطاق المتغير، لن يتم تعريفه - وليس كمعرف
يحتوي على قيمة undefined
، ولكن كما لو لم يتم الإعلان عنها.
اعتمادًا على الكلمة الرئيسية التي تستخدمها لتعريف أحد المتغيرات والسياق الذي ويمكنك تعريفه، ويمكنك تحديد نطاق المتغيرات لحظر العبارات (حظر النطاق)، دوال فردية (نطاق الدالة)، أو تطبيق JavaScript بالكامل (النطاق العام).
حظر النطاق
أي متغيّر تعلن عنه باستخدام let
أو const
يتم تحديده إلى أقرب موضع له.
تحتوي على عبارة حظر
مما يعني أنه لا يمكن الوصول إلى المتغير إلا داخل هذه الكتلة. جارٍ محاولة
يؤدي الوصول إلى متغير ذو نطاق حظر خارج نطاق الكتلة الذي يتضمنه إلى حدوث نفس
خطأ كمحاولة للوصول إلى متغيّر غير موجود:
{
let scopedVariable = true;
console.log( scopedVariable );
}
> true
scopedVariable
> ReferenceError: scopedVariable is not defined
وبالنسبة إلى JavaScript، لا يتوفّر متغيّر ضمن نطاق الحظر. خارج الكتلة التي تحتوي عليها. على سبيل المثال، يمكنك الإعلان عن ثابتة داخل كتلة، ثم الإعلان عن ثابت آخر خارج تلك الكتلة التي تستخدم المعرّف نفسه:
{
const myConstant = false;
}
const myConstant = true;
scopedConstant;
> true
على الرغم من أنه لا يمكن تمديد المتغير المُعلَن عنه في كتلته الرئيسية، فإنه يتم متاحة لجميع الوحدات الفرعية:
{
let scopedVariable = true;
{
console.log( scopedVariable );
}
}
> true
يمكن تغيير قيمة المتغيّر المعلَن من داخل مجموعة تابعة:
{
let scopedVariable = false;
{
scopedVariable = true;
}
console.log( scopedVariable );
}
> true
يمكن إعداد متغيّر جديد باستخدام let
أو const
داخل عنصر تابع
بدون أخطاء، حتى لو تم استخدام نفس المعرف كمتغير في
حظر المحتوى الرئيسي:
{
let scopedVariable = false;
{
let scopedVariable = true;
}
console.log( scopedVariable );
}
> false
نطاق الوظيفة
يتم تحديد نطاق المتغيّرات المعلَنة باستخدام var
وفقًا لأقرب دالة تحتوي على قيمة المتغيّرات.
(أو كتلة إعداد ثابتة داخل فئة).
function myFunction() {
var scopedVariable = true;
return scopedVariable;
}
scopedVariable;
> ReferenceError: scopedVariable is not defined
لا يزال هذا هو الحال بعد استدعاء الدالة. على الرغم من أن تهيئة المتغير أثناء تنفيذ الدالة، فلا يزال هذا المتغير غير متاحة خارج نطاق الدالة:
function myFunction() {
var scopedVariable = true;
return scopedVariable;
}
scopedVariable;
> ReferenceError: scopedVariable is not defined
myFunction();
> true
scopedVariable;
> ReferenceError: scopedVariable is not defined
النطاق العمومي
يتوفر المتغير العمومي في جميع أنحاء تطبيق JavaScript بالكامل، داخل أي وجميع الكتل والدوال، إلى أي نص برمجي على الصفحة.
ورغم أن هذا قد يبدو وكأنه إعداد افتراضي مرغوب فيه، إلا أن متغيرات أي جزء من إمكانية الوصول إليها وتعديلها إلى إضافة أعباء غير ضرورية، أو قد تتسبب في التعارضات مع المتغيرات في أي مكان آخر في أحد التطبيقات بنفس المعرف. ينطبق ذلك على جميع رموز JavaScript المستخدمة في عرض الصفحة. بما في ذلك مكتبات الجهات الخارجية وإحصاءات المستخدم لذلك، من المهم أفضل الممارسات لتجنُّب تلوث النطاق العمومي كلما أمكن ذلك.
يشير هذا المصطلح إلى أي متغيّر تم الإعلان عنه باستخدام var
خارج دالة رئيسية، أو باستخدام let
أو
const
خارج نطاق المجموعة الرئيسية عمومًا:
var functionGlobal = true; // Global
let blockGlobal = true; // Global
{
console.log( blockGlobal );
console.log( functionGlobal );
}
> true
> true
(function() {
console.log( blockGlobal );
console.log( functionGlobal );
}());
> true
> true
إن تعيين قيمة لمتغير دون الإعلان عنه صراحةً (أي من خلال
عدم استخدام var
أو let
أو const
لإنشائها) إلى رفع متغير إلى
نطاق عمومي، حتى عند التهيئة داخل دالة أو كتلة. متغير
التي يتم إنشاؤها باستخدام هذا النمط أحيانًا باسم "عالمي ضمني".
function myFunction() {
globalVariable = "global";
return globalVariable
}
myFunction()\
> "global"
globalVariable\
> "global"
الرفع المتغير
يتم نقل المتغيرات وتعريفات الدوال في أعلى نطاقها،
مما يعني أن مترجم JavaScript يعالج أي متغير تم تعريفه في أي
في نص برمجي ونقله بشكل فعال إلى السطر الأول من المرفق
النطاق قبل تنفيذ البرنامج النصي. وهذا يعني أن المتغير الذي تم تعريفه باستخدام
يمكن الرجوع إلى var
قبل تعريف المتغيّر بدون مواجهة
خطأ:
hoistedVariable
> undefined
var hoistedVariable;
ونظرًا لأنه تتم استضافة تعريف المتغير فقط، وليس الإعداد،
المتغيّرات التي لم يتم الإعلان عنها صراحةً باستخدام var
أو let
أو const
لا يتم رفعها:
unhoistedVariable;
> Uncaught ReferenceError: unhoistedVariable is not defined
unhoistedVariable = true;
كما ذكرنا سابقًا، المتغير المُعلَن عنه ولكنه غير مهيأ
تم تعيينه لقيمة undefined
. ينطبق هذا السلوك على المتغير المرفوع
أيضًا، ولكن فقط للتعريفات باستخدام var
.
hoistedVariable
> undefined
var hoistedVariable = 2 + 2;
hoistedVariable\
> 4
هذا السلوك غير البديهي يعد إلى حد كبير الاحتفاظ بقرارات التصميم التي يتم اتخاذها في والإصدارات الأقدم من JavaScript، ولا يمكن تغييرها بدون المخاطرة اختراق المواقع الحالية.
يتعامل كل من let
وconst
مع هذا السلوك من خلال عرض خطأ عند
يتم الوصول إلى المتغير قبل إنشائه:
{
hoistedVariable;
let hoistedVariable;
}
> Uncaught ReferenceError: can't access lexical declaration 'hoistedVariable' before initialization
يختلف هذا الخطأ عن "hoistedVariable لم يتم تعريفه" خطأ
المستخدم عند محاولة الوصول إلى متغير غير مُعرَّف. لأنّ JavaScript
الذي رفع فيه المتغير، فإنه يدرك أنه سيتم إنشاء المتغير داخل
للنطاق المحدد. ومع ذلك، فبدلاً من إتاحة هذا المتغير قبل
تصريح بقيمة undefined
، يعرض المُترجم خطأً.
يُقال إنّ المتغيّرات المعلَنة باستخدام let
أو const
(أو class
) موجودة في
"منطقة زمنية ثابتة" ("TDZ") من بداية كتلة التضمين حتى
في الرمز حيث تم تعريف المتغير.
تجعل المنطقة الثابتة الزمنية سلوك let
أكثر سهولة من var
المؤلفين. إنّ تصميم "const
" مهم أيضًا. لأن الثوابت لا يمكن
ثابتًا يرتفع إلى قمة نطاقه ومنحه قيمة ضمنية
تعذّر إعداد من undefined
باستخدام قيمة مفيدة.
التحقق من فهمك
ما هي أنواع الأحرف التي يمكنك بدء المعرّف بها؟
ما هي الطريقة المفضلة للتعريف عن متغير قيمته في أي وقت؟