3. أساسيات جافا سكريبت
ملاحظة: في ما يلي، سيشير المصطلح [Javascript] دائمًا إلى المعيار ECMAScript 6.
داخل مشروع جافا سكريبت السابق، قم بإنشاء مجلد [bases]. سنضع فيه أمثلة هذا القسم:

3.1. نص برمجي [bases-01]
لتقديم أساسيات PHP7، استخدمنا الكود التالي (انظر الفقرة الرابط):
<?php
// هذا تعليق
// متغير مستخدم دون أن يتم إعلانه
$nom = "dupont";
// عرض على الشاشة
print "nom=$nom\n";
// جدول يحتوي على عناصر من أنواع مختلفة
$tableau = array("un", "deux", 3, 4);
// عدد عناصره
$n = count($tableau);
// حلقة
for ($i = 0; $i < $n; $i++) {
print "tableau[$i]=$tableau[$i]\n";
}
// تهيئة متغيرين بمحتوى مصفوفة
list($chaine1, $chaine2) = array("chaine1", "chaine2");
// تسلسل السلسلتين
$chaine3 = $chaine1 . $chaine2;
// عرض النتيجة
print "[$chaine1,$chaine2,$chaine3]\n";
// استخدام الدالة
affiche($chaine1);
// يمكن معرفة نوع المتغير
afficheType("n", $n);
afficheType("chaine1", $chaine1);
afficheType("tableau", $tableau);
// يمكن أن يتغير نوع المتغير أثناء التنفيذ
$n = "a changé";
afficheType("n", $n);
// يمكن أن ترجع الدالة نتيجة
$res1 = f1(4);
print "res1=$res1\n";
// يمكن أن ترجع الدالة مصفوفة من القيم
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";
// كان من الممكن استرداد هذه القيم في مصفوفة
$t = f2();
for ($i = 0; $i < count($t); $i++) {
print "t[$i]=$t[$i]\n";
}
// اختبارات
for ($i = 0; $i < count($t); $i++) {
// لا يعرض سوى السلاسل
if (getType($t[$i]) === "string") {
print "t[$i]=$t[$i]\n";
}
}
// مشغلات المقارنة == و ===
if("2"==2){
print "avec l'opérateur ==, la chaîne 2 est égale à l'entier 2\n";
}else{
print "avec l'opérateur ==, la chaîne 2 n'est pas égale à l'entier 2\n";
}
if("2"===2){
print "avec l'opérateur ===, la chaîne 2 est égale à l'entier 2\n";
}
else{
print "avec l'opérateur ===, la chaîne 2 n'est pas égale à l'entier 2\n";
}
// اختبارات أخرى
for ($i = 0; $i < count($t); $i++) {
// يعرض فقط الأعداد الصحيحة >10
if (getType($t[$i]) === "integer" and $t[$i] > 10) {
print "t[$i]=$t[$i]\n";
}
}
// حلقة while
$t = [8, 5, 0, -2, 3, 4];
$i = 0;
$somme = 0;
while ($i < count($t) and $t[$i] > 0) {
print "t[$i]=$t[$i]\n";
$somme += $t[$i]; //$somme=$somme+$t[$i]
$i++; //$i=$i+1
}//بينما
print "somme=$somme\n";
// نهاية البرنامج
exit;
//----------------------------------
function affiche($chaine) {
// يعرض $chaine
print "chaine=$chaine\n";
}
//يعرض
//----------------------------------
function afficheType($name, $variable) {
// يعرض نوع $variable
print "type[variable $" . $name . "]=" . getType($variable) . "\n";
}
//afficheType
//----------------------------------
function f1($param) {
// يضيف 10 إلى $param
return $param + 10;
}
//----------------------------------
function f2() {
// يعرض 3 قيم
return array("un", 0, 100);
}
?>
عند ترجمته إلى جافا سكريبت، يصبح الكود كما يلي:
'use strict';
// هذا تعليق
// ثابت
const nom = "dupont";
// عرض على الشاشة
console.log("nom : ", nom);
// مصفوفة تحتوي على عناصر من أنواع مختلفة
const tableau = ["un", "deux", 3, 4];
// عدد عناصره
let n = tableau.length;
// حلقة
for (let i = 0; i < n; i++) {
console.log("tableau[", i, "] = ", tableau[i]);
}
// تهيئة متغيرين بمحتوى مصفوفة
let [chaine1, chaine2] = ["chaine1", "chaine2"];
// تسلسل السلسلتين
const chaine3 = chaine1 + chaine2;
// عرض النتيجة
console.log([chaine1, chaine2, chaine3]);
// استخدام الدالة
affiche(chaine1);
// يمكن معرفة نوع المتغير
afficheType("n", n);
afficheType("chaine1", chaine1);
afficheType("tableau", tableau);
// يمكن أن يتغير نوع المتغير أثناء التنفيذ
n = "a changé";
afficheType("n", n);
// يمكن أن ترجع الدالة نتيجة
let res1 = f1(4);
console.log("res1=", res1);
// يمكن أن ترجع الدالة مصفوفة من القيم
let res2, res3;
[res1, res2, res3] = f2();
console.log("(res1,res2,res3)=", [res1, res2, res3]);
// كان من الممكن استرداد هذه القيم في مصفوفة
let t = f2();
for (let i = 0; i < t.length; i++) {
console.log("t[i]=", t[i]);
}
// اختبارات
for (let i = 0; i < t.length; i++) {
// لا تعرض سوى السلاسل
if (typeof (t[i]) === "string") {
console.log("t[i]=", t[i]);
}
}
// مشغلات المقارنة == و ===
if ("2" == 2) {
console.log("avec l'opérateur ==, la chaîne 2 est égale à l'entier 2");
} else {
console.log("avec l'opérateur ==, la chaîne 2 n'est pas égale à l'entier 2");
}
if ("2" === 2) {
console.log("avec l'opérateur ===, la chaîne 2 est égale à l'entier 2");
} else {
console.log("avec l'opérateur ===, la chaîne 2 n'est pas égale à l'entier 2");
}
// اختبارات أخرى
for (let i = 0; i < t.length; i++) {
// لا يعرض سوى الأعداد الصحيحة الأكبر من 10
if (typeof (t[i]) === "number" && Math.floor(t[i]) === t[i] && t[i] > 10) {
console.log("t[i]=", t[i]);
}
}
// حلقة while
t = [8, 5, 0, -2, 3, 4];
let i = 0;
let somme = 0;
while (i < t.length && t[i] > 0) {
console.log("t[i]=", t[i]);
somme += t[i];
i++;
}
console.log("somme=", somme);
// توقف البرنامج لعدم وجود كود قابل للتنفيذ
//يعرض
//----------------------------------
function affiche(chaine) {
// يعرض سلسلة
console.log("chaine=", chaine);
}
//afficheType
//----------------------------------
function afficheType(name, variable) {
// يعرض نوع المتغير
console.log("type[variable ", name, "]=", typeof (variable));
}
//----------------------------------
function f1(param) {
// يضيف 10 إلى param
return param + 10;
}
//----------------------------------
function f2() {
// يعرض 3 قيم
return ["un", 0, 100];
}
دعونا نعلق على الاختلافات بين الرموز PHP و ECMAScript 6 مع الإعلان [use strict] (السطر 1):
- الاختلاف الأول هو أنه في ECMAScript يتم تعريف المتغيرات باستخدام الكلمات الرئيسية التالية:
- [let] لإعلان متغير يمكن أن تتغير قيمته أثناء تنفيذ الكود؛
- [const] لإعلان متغير لن تتغير قيمته (أي ثابت) أثناء تنفيذ الكود؛
- يمكن أيضًا استخدام الكلمة الرئيسية [var] بدلاً من [let]. كانت هذه هي الكلمة الرئيسية المستخدمة مع ECMAScript 5. لن نستخدمها في هذه الدورة؛
- السطر 6: يمكن لطريقة العرض [console.log] عرض جميع أنواع البيانات: سلاسل، أرقام، قيم منطقية، مصفوفات، كائنات. لا تستطيع الطريقة PHP [print] عرض المصفوفات والكائنات بشكل أصلي. في التعبير [console.log]، [console] هو كائن و [log] هي طريقة لهذا الكائن؛
- السطر 8: الجداول في جافا سكريبت هي كائنات يُشار إليها بواسطة مؤشر. عندما نكتب:
const tableau = ["un", "deux", 3, 4];
تكون المتغير [tableau] مؤشرًا على المصفوفة الحرفية ["un", "deux", 3, 4]. لا يؤدي تعديل محتوى المصفوفة إلى تعديل مؤشرها. لذلك، غالبًا ما يتم تعريف المصفوفة باستخدام الكلمة الرئيسية [const]. في PHP، لا يُشار إلى المصفوفة بواسطة مؤشر. إنها بيانات حرفية؛
- السطر 12: يتم إعلان متغير الحلقة [i] (let) داخل الحلقة. الكلمة الرئيسية [let] تتوافق مع نطاق الكتلة (الكود بين الأقواس المتعقبة). وبالتالي، فإن المتغير [i] في السطر 12 معروف فقط داخل الحلقة؛
- السطر 18: عامل ربط السلاسل هو عامل + في جافا سكريبت، و. في PHP. ومن خصائص هذا العامل أنه له الأسبقية على عامل الجمع +. وبالتالي:
- في PHP، ‘1’ +2 يعطي الرقم 3؛
- في جافا سكريبت، ‘1’+2 يعطي السلسلة ‘12’؛
- السطر 20: [console.log] يمكنه عرض الجداول؛
- السطر 82: في Javascript، لا يمكن تحديد نوع معلمات الدالة؛
- السطر 91: يسمح عامل [typeof] بمعرفة نوع البيانات. هناك أربعة أنواع: عدد، سلسلة أحرف، منطقية، وكائن. تجدر الإشارة إلى أنه في جافا سكريبت لا يوجد نوع [integer] ولا نوع [tableau]. كما ذكرنا سابقًا، يتم التعامل مع الجداول عبر المؤشرات وتندرج ضمن فئة الكائنات؛
- السطور 50-59: كما هو الحال في PHP، يوجد في جافا سكريبت عاملان للمقارنة، == و ‘===’، لهما نفس المعنى كما في PHP. غالبًا ما يشير ESLint إلى عامل == على أنه خطأ محتمل. سنستخدم عامل ‘===’ بشكل منهجي؛
- السطر 79: كان من الممكن استخدام الأمر [return]، لكن الأمر ESLint يُصدر تحذيرًا يفيد بأن الأمر [return] يجب ألا يُستخدم إلا داخل دالة؛
لنقم بتنفيذ هذا الكود:

نتائج التنفيذ:
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\bases\bases-01.js"
nom : dupont
tableau[ 0 ] = un
tableau[ 1 ] = deux
tableau[ 2 ] = 3
tableau[ 3 ] = 4
[ 'chaine1', 'chaine2', 'chaine1chaine2' ]
chaine= chaine1
type[variable n ]= number
type[variable chaine1 ]= string
type[variable tableau ]= object
type[variable n ]= string
res1= 14
(res1,res2,res3)= [ 'un', 0, 100 ]
t[ 0 ]= un
t[ 1 ]= 0
t[ 2 ]= 100
t[ 0 ]= un
avec l'opérateur ==, la chaîne 2 est égale à l'entier 2
avec l'opérateur ===, la chaîne 2 n'est pas égale à l'entier 2
t[ 2 ]= 100
t[ 0 ]= 8
t[ 1 ]= 5
somme= 13
[Done] exited with code=0 in 0.316 seconds
في الكود المكتوب، يشير ESLINT إلى خطأين:

- عند تمرير المؤشر فوق السطر الأحمر للتحذير، تظهر رسالة الخطأ [3]. هنا، لا يفهم ESLint أننا نقارن بين ثابتين. يجب أن يكون أحد المعاملين متغيرًا؛
- في [4]، تتيح خيار [Quick Fix] إزالة التحذير إذا قررنا عدم تصحيح الخطأ؛

- في [5]، يمكن تعطيل التحذير للسطر الحالي أو للملف بأكمله. نختار الخيار الأخير هنا. يتم بعد ذلك إنشاء السطر [6] في بداية الملف؛
3.2. البرنامج النصي [bases-02]
يُظهر البرنامج النصي [bases-02] استخدام الكلمات الرئيسية [let] و [const]:
'use strict';
// لتهيئة متغير، نستخدم let أو const
// let للمتغيرات
let x = 4;
x++;
console.log(x);
// const للثوابت
const y = 10;
x += y;
// محظور
y++;
- السطر 11 يتسبب في حدوث خطأ عند التنفيذ [1-2]. يتم الإبلاغ عنه بواسطة ESLint قبل التنفيذ [3]:

3.3. نص برمجي [bases-03]
يفحص البرنامج النصي [bases-03] نطاق المتغيرات في جافا سكريبت:
'use strict';
// نطاق المتغيرات
let count = 1;
function doSomething() {
// count معروف هنا
console.log("count=",count);
}
// استدعاء
doSomething();
- المتغير [count] المعلن خارج الدالة [doSomething] معروف مع ذلك في هذه الدالة. وهذا يمثل اختلافًا جوهريًا عن PHP؛
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\bases\bases-03.js"
count= 1
[Done] exited with code=0 in 0.3 seconds
3.4. نص برمجي [bases-04]
تخفي متغير محلي متغيرًا عامًا يحمل نفس الاسم:
'use strict';
// نطاق المتغيرات
const count = 1;
function doSomething() {
// المتغير المحلي يخفي المتغير العام
const count = 2;
console.log("count inside function=",count);
}
// متغير عام
console.log("count outside function=",count);
// متغير محلي
doSomething();
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\bases\bases-04.js"
count outside function= 1
count inside function= 2
[Done] exited with code=0 in 0.246 seconds
3.5. نص برمجي [bases-05]
المتغير المُعرَّف داخل دالة ما لا يُعرف خارجها:
'use strict';
// نطاق المتغيرات
function doSomething() {
// متغير محلي للدالة
const count = 2;
console.log("count inside function=", count);
}
// هنا count غير معروف
console.log("count outside function=", count);
doSomething();
ESLint يُبلغ عن خطأ في السطر 9:

3.6. البرنامج النصي [bases-06]
تحدد الكلمات الرئيسية [let] و [const] متغيرات نطاق [bloc] (الرمز بين الأقواس) ولكن ليس الكلمة الرئيسية [var]:
'use strict';
// تسمح الكلمة الرئيسية [let] بتعريف متغير ذي نطاق كتلة
{
// المتغير [count] معروف فقط في هذا الكتلة
let count = 1;
console.log("count=", count);
}
// هنا المتغير [count] غير معروف
count++;
// تسمح الكلمة الرئيسية [const] بتعريف متغير نطاق الكتلة
{
// المتغير [count2] معروف فقط في هذا الكتلة
const count2 = 1;
console.log("count=", count2);
}
// هنا المتغير [count2] غير معروف
count2++;
// الكلمة الرئيسية [var] لا تسمح بتعريف متغير نطاق الكتلة
{
// المتغير [count3] سيكون معروفًا بشكل عام
var count3 = 1;
console.log("count=", count3);
}
// هنا المتغير [count3] معروف
count3++;
تعليقات
- السطر 5: المتغير [count] معروف فقط في كتلة الكود التي تم إعلانه فيها (الأسطر 3-7)؛
- السطر 14: الثابت [count2] معروف فقط في كتلة الكود التي تم إعلانه فيها (الأسطر 12-16)؛
- السطر 23: المتغير [count3] معروف خارج كتلة الكود التي تم إعلانه فيها (الأسطر 21-25)؛
تُعلن ESLint الأخطاء التالية:

لهذه الأسباب المتعلقة بنطاق الكتلة، لن نستخدم بعد ذلك سوى الكلمات الرئيسية [let] و [const].
3.7. نص برمجي [bases-07]
أنواع البيانات في جافا سكريبت:
'use strict';
// نوع البيانات jS
const var1 = 10;
const var2 = "abc";
const var3 = true;
const var4 = [1, 2, 3];
const var5 = {
nom: 'axèle'
};
const var6 = function () {
return +3;
}
// عرض الأنواع
console.log("typeof(var1)=", typeof (var1));
console.log("typeof(var2)=", typeof (var2));
console.log("typeof(var3)=", typeof (var3));
console.log("typeof(var4)=", typeof (var4));
console.log("typeof(var5)=", typeof (var5));
console.log("typeof(var6)=", typeof (var6));
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\bases\bases-07.js"
typeof(var1)= number
typeof(var2)= string
typeof(var3)= boolean
typeof(var4)= object
typeof(var5)= object
typeof(var6)= function
[Done] exited with code=0 in 0.26 seconds
تعليقات
- السطر 7 (الكود): المصفوفة هي كائن. وبناءً على ذلك، فإن [var4] هو مؤشر إلى المصفوفة، وليس المصفوفة نفسها؛
- السطر 8 (الكود): [var5] هو مؤشر إلى كائن حرفي. سنرى أن الكائنات الحرفية في جافا سكريبت تشبه إلى حد كبير مثيلات فئة PHP. يتم الإشارة إليها أيضًا عبر مؤشرات؛
- السطر 11 (الكود): يمكن أن تكون المتغيرات من النوع [fonction] (السطر 7 من النتائج)؛
3.8. نص برمجي [bases-08]
يُظهر هذا البرنامج النصي التغييرات المحتملة في الأنواع في جافا سكريبت.
'use strict';
// التغييرات الضمنية في الأنواع
// النوع -->bool
console.log("---------------[Conversion implicite vers un booléen]------------------------------");
showBool("abcd");
showBool("");
showBool([1, 2, 3]);
showBool([]);
showBool(null);
showBool(0.0);
showBool(0);
showBool(4.6);
showBool({});
showBool(undefined);
function showBool(data) {
// يتم تحويل البيانات إلى منطقية تلقائيًا في الاختبار التالي
console.log("[data=", data, "], [type(data)]=", typeof (data), "[valeur booléenne(data)]=", data ? true : false);
}
// تغييرات ضمنية في النوع إلى نوع رقمي
console.log("---------------[Conversion implicite vers un nombre]------------------------------");
showNumber("12");
showNumber("45.67");
showNumber("abcd");
function showNumber(data) {
// data + 1 لا يعمل لأن jS يقوم بضم سلاسل بدلاً من الجمع
const nombre = data * 1;
console.log("[data=", data, "], [type(data)]=", typeof (data), "[nombre]=", nombre, "[type(nombre)]=", typeof (nombre));
}
// تغييرات صريحة للأنواع إلى قيمة منطقية
console.log("---------------[Conversion explicite vers un booléen]------------------------------");
showBool2("abcd");
showBool2("");
showBool2([1, 2, 3]);
showBool2([]);
showBool2(null);
showBool2(0.0);
showBool2(0);
showBool2(4.6);
showBool2({});
showBool2(undefined);
function showBool2(data) {
// يتم تحويل data إلى منطقية بشكل صريح في الاختبار التالي
console.log("[", data, "], [type(data)]=", typeof (data), "[valeur booléenne(data)]=", Boolean(data));
}
// تغييرات صريحة في النوع إلى Number
console.log("---------------[Conversion explicite vers un nombre]------------------------------");
showNumber2("12.45");
showNumber2(67.8);
showNumber2(true);
showNumber2(null);
function showNumber2(data) {
const nombre = Number(data);
console.log("[data=", data, "], [type(data)]=", typeof (data), "[nombre]=", nombre, "[type(nombre)]=", typeof (nombre));
}
// إلى String
console.log("---------------[Conversion explicite vers un string]------------------------------");
showString(5);
showString(6.7);
showString(false);
showString(null);
function showString(data) {
const chaîne = String(data);
console.log("[data=", data, "], [type(data)]=", typeof (data), "[chaîne]=", chaîne, "[type(chaîne)]=", typeof (chaîne));
}
// بعض التحويلات الضمنية غير المتوقعة
console.log("---------------[Autres cas]------------------------------");
const string1 = '1000.78';
// تسلسل سلاسل النص بشكل افتراضي
const data1 = string1 + 1.034;
console.log("data1=", data1, "type=", typeof (data1));
const data2 = 1.034 + string1;
console.log("data2=", data2, "type=", typeof (data2));
// تحويل صريح إلى رقم
const data3 = Number(string1) + 1.034;
console.log("data3=", data3, "type=", typeof (data3));
// تم تحويل true إلى الرقم 1
const data4 = true * 1.18;
console.log("data4=", data4, "type=", typeof (data4));
// يتم تحويل false إلى الرقم 0
const data5 = false * 1.18;
console.log("data5=", data5, "type=", typeof (data5));
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Data\st-2019\dev\es6\javascript\bases\bases-08.js"
---------------[Conversion implicite vers un booléen]------------------------------
[data= abcd ], [type(data)]= string [valeur booléenne(data)]= true
[data= ], [type(data)]= string [valeur booléenne(data)]= false
[data= [ 1, 2, 3 ] ], [type(data)]= object [valeur booléenne(data)]= true
[data= [] ], [type(data)]= object [valeur booléenne(data)]= true
[data= null ], [type(data)]= object [valeur booléenne(data)]= false
[data= 0 ], [type(data)]= number [valeur booléenne(data)]= false
[data= 0 ], [type(data)]= number [valeur booléenne(data)]= false
[data= 4.6 ], [type(data)]= number [valeur booléenne(data)]= true
[data= {} ], [type(data)]= object [valeur booléenne(data)]= true
[data= undefined ], [type(data)]= undefined [valeur booléenne(data)]= false
---------------[Conversion implicite vers un nombre]------------------------------
[data= 12 ], [type(data)]= string [nombre]= 12 [type(nombre)]= number
[data= 45.67 ], [type(data)]= string [nombre]= 45.67 [type(nombre)]= number
[data= abcd ], [type(data)]= string [nombre]= NaN [type(nombre)]= number
---------------[Conversion explicite vers un booléen]------------------------------
[ abcd ], [type(data)]= string [valeur booléenne(data)]= true
[ ], [type(data)]= string [valeur booléenne(data)]= false
[ [ 1, 2, 3 ] ], [type(data)]= object [valeur booléenne(data)]= true
[ [] ], [type(data)]= object [valeur booléenne(data)]= true
[ null ], [type(data)]= object [valeur booléenne(data)]= false
[ 0 ], [type(data)]= number [valeur booléenne(data)]= false
[ 0 ], [type(data)]= number [valeur booléenne(data)]= false
[ 4.6 ], [type(data)]= number [valeur booléenne(data)]= true
[ {} ], [type(data)]= object [valeur booléenne(data)]= true
[ undefined ], [type(data)]= undefined [valeur booléenne(data)]= false
---------------[Conversion explicite vers un nombre]------------------------------
[data= 12.45 ], [type(data)]= string [nombre]= 12.45 [type(nombre)]= number
[data= 67.8 ], [type(data)]= number [nombre]= 67.8 [type(nombre)]= number
[data= true ], [type(data)]= boolean [nombre]= 1 [type(nombre)]= number
[data= null ], [type(data)]= object [nombre]= 0 [type(nombre)]= number
---------------[Conversion explicite vers un string]------------------------------
[data= 5 ], [type(data)]= number [chaîne]= 5 [type(chaîne)]= string
[data= 6.7 ], [type(data)]= number [chaîne]= 6.7 [type(chaîne)]= string
[data= false ], [type(data)]= boolean [chaîne]= false [type(chaîne)]= string
[data= null ], [type(data)]= object [chaîne]= null [type(chaîne)]= string
---------------[Autres cas]------------------------------
data1= 1000.781.034 type= string
data2= 1.0341000.78 type= string
data3= 1001.814 type= number
data4= 1.18 type= number
data5= 0 type= number