التعبير عبارة عن عبارة في JavaScript ، وسيقوم مترجم JavaScript بحساب النتيجة. الكميات الشائعة الاستخدام في البرامج هي أبسط أنواع التعبيرات التي هي المتغيرات. الأسماء المتغيرة هي أيضًا تعبير بسيط ، وقيمتها هي القيمة المخصصة للمتغير.
تتكون التعبيرات المعقدة من تعبيرات بسيطة. على سبيل المثال ، يتكون تعبير الوصول إلى صفيف من تعبير يمثل صفيفًا وأقواسًا مربعة وتعبيرًا صحيحًا. عملية التعبير الجديدة التي تشكلها هي قيمة العنصر في موضع معين في الصفيف. نفس الرسالة
يتكون تعبير مكالمة رقم من تعبير يمثل كائن دالة و 0 تعبيرات المعلمة 0. الطريقة الأكثر شيوعًا في الجمع بين التعبيرات البسيطة في التعبيرات المعقدة هي المشغلين.
سيشرح هذا الفصل (هذه المقالة) جميع مشغلي JavaScript. كما يفسر التعبيرات التي لا تشمل العوامل (مثل الوصول إلى عناصر الصفيف ومكالمات الوظائف) ، وأسلوب بناء الجملة وأسلوب البرمجة يشبهان إلى حد كبير تلك الموجودة في لغة C.
1. تعبير العنصر
أبسط تعبير هو "التعبير الأصلي" ، وهو أصغر وحدة للتعبير - لا تحتوي على تعبيرات أخرى. التعبيرات الأصلية في جافا سكريبت تحتوي على ثوابت أو كميات مباشرة. الكلمات الرئيسية والمتغيرات.
الكمية المباشرة هي قيمة ثابتة تظهر مباشرة في البرنامج. تبدو مثل:
نسخة الكود كما يلي:
1.23 // الكمية المباشرة
"مرحبا" // قف كمية مباشرة
/ نمط/ // التعبير العادي كمية مباشرة
تشكل بعض الكلمات المحجوزة في JavaScript التعبير الأصلي
نسخة الكود كما يلي:
صواب / /قيمة منطقية: صحيح
خطأ / /خطأ
NULL // إرجاع القيمة: فارغة
هذا // إرجاع الكائن "الحالي"
من خلال تعلم الفصل 3 ، على عكس الكلمات الرئيسية الأخرى ، فإن هذا ليس ثابتًا ، والقيم التي تعيدها في أجزاء مختلفة من البرنامج مختلفة أيضًا. غالبًا ما تظهر هذه الكلمة الرئيسية في البرمجة الموجهة للكائنات. هذا يعيد كائن الطريقة المربعة.
أخيرًا ، التعبير الأصلي الثالث هو متغير
نسخة الكود كما يلي:
I // إرجاع قيمة المتغير أنا
Sum // إرجاع قيمة المجموع
غير محدد // هو متغير عالمي ، على عكس فارغة ، فهي ليست كلمة رئيسية
2. تعبيرات تهيئة الكائنات والصفائف.
تهيئة الكائن والمصفوفة هي في الواقع كائنات ومصفوفات تم إنشاؤها حديثًا. تسمى هذه التعبيرات المهيئة أحيانًا "الكائن المباشر للكائن" و "الصفيف المباشر". ومع ذلك ، على عكس الكميات المباشرة المنطقية ، فهي ليست تعبيرات أصلية لأن الأعضاء أو العناصر التي تحتوي عليها هي التعبيرات الفرعية.
بناء جملة تعبير التهيئة من صفيف بسيط للغاية ، لنبدأ أدناه
يتكون تعبير التهيئة لمجموعة من زوج من الأقواس المربعة وقائمة مفصولة فاصلة. نتيجة التهيئة هي صفيف تم إنشاؤه حديثًا. عناصر الصفيف هي قيم مفصولة بالتعبيرات.
[] // صفيف فارغ ؛ [] اترك فارغًا فيه يعني أن الصفيف ليس له عناصر
[1+2،3+4] // صفيف مع عنصرين ، الأول هو 3 ، والثاني هو 7
يمكن أن يكون تعبير تهيئة العنصر في تعبير تهيئة الصفيف تعبير تهيئة الصفيف. وهذا يعني ، يمكن أن يتم تجديد التعبيرات
نسخة الكود كما يلي:
var mat = [[1،2،3] ، [4،5،6] ، [7،8،9]] ؛
يمكن حذف العناصر بين القوائم في الصفيف ، وسيتم ملء المساحة مع غير محددة. على سبيل المثال:
نسخة الكود كما يلي:
var a = [1 ،،، 5]
أربعة من العناصر غير محددة. يتم ترك فاصلة في نهاية الكمية المباشرة من الصفيف ، ولن يتم إنشاء عنصر جديد ذي قيمة غير محددة.
تشبه تعبيرات تهيئة الكائنات تعبيرات تهيئة الصفيف ، باستثناء أن الأقواس المربعة يتم استبدالها بأقواس مجعد. ويحتوي كل تعبير كلمة على اسم سمة وغير كولون كبادئة.
نسخة الكود كما يلي:
var p = {x: 2.1 ، y: -3} // كائن مع عضوين سمة
var q = {} ؛ // كائن فارغ
QX = 2.1 ؛ qy = -3 ؛ // أعضاء السمة من Q هم نفس أعضاء p
يمكن أيضًا تداخل الكائن مباشرة ، على سبيل المثال
نسخة الكود كما يلي:
var anh = {left: {x: 2 ، y: 3} ،
اليمين: {x: 4 ، y: 5}}
عندما تحسب JavaScript قيمة تعبير تهيئة الكائن ، يتم حساب تعبيرات الكائن في كل مرة ، ولا يتعين عليها تضمين قيم ثابتة: يمكن أن تكون أي تعبير JavaScript. وبالمثل ، يمكن أن يكون اسم الخاصية في الكمية المباشرة للكائن سلسلة بدلاً من معرف. (إنه مفيد للغاية عندما يتم استخدام الكلمات المحجوزة فقط أو بعض المعرفات غير القانونية كأسماء السمات على هذا الخط)
نسخة الكود كما يلي:
var side = 1 ؛
var square = {"left": {x: px ، y: py} ،
'right': {x: p.x+side ، y: p.y+side}}
سيناقش الفصل 67 أيضًا تعبيرات التهيئة للكائنات والمصفوفات مرة أخرى.
3. تعبيرات الوظيفة
تعبير تعريف الوظيفة يحدد وظيفة JavaScript. قيمة التعبير هي هذه الوظيفة المحددة حديثًا. بمعنى ما ، يمكن أن تصبح تعبيرات تعريف الوظائف كميات وظيفية مباشرة ، ويمكن تسمية تعبيرات الوظائف "كميات الوظيفة المباشرة" ، بعد أن تسمى جميع تعبيرات تهيئة الكائن أيضًا "كميات الكائن المباشر". يحتوي تعبير تعريف الوظيفة النموذجي على وظيفة الكلمة الرئيسية ، متبوعًا بزوج من الأقواس ، وقائمة مفصولة بفاصلة ، والقائمة تحتوي على 0 أو أكثر من المعرفات (أسماء المعلمات). ثم اتبع شريحة رمز JavaScript (جسم الوظيفة) ملفوفة في أقواس مجعد.
var square = function (x) {return x*x} ؛
يمكن أن تحتوي تعبيرات تعريف الوظيفة أيضًا على اسم الوظيفة. يمكن أيضًا تحديد الوظائف بواسطة عبارات الوظائف ، بدلاً من تعبيرات الوظائف. سيتم وصف المزيد من المحتوى في الفصل 8.
4. تعبير الوصول إلى السمة
تحصل عملية تعبير الوصول إلى السمة على قيمة كائن أو عنصر صفيف. تحدد JavaScript طريقتين للوصول إلى الممتلكات.
نسخة الكود كما يلي:
تعبير . المسنن
التعبير [التعبير]
الطريقة الأولى هي كتابة تعبير تليها فترة ومعرف. يحدد التعبير الكائن ، ويحدد المعرف السمة Mingchuan للوصول.
يتم كتابة الفصل 2 باستخدام قوسين مربع ، وهو تعبير (هذه الطريقة مناسبة للكائنات والصفائف). يحدد التعبير الثاني خاصية Mingchuan التي سيتم الوصول إليها أو الفهرس الذي يمثل عنصر الصفيف الذي سيتم الوصول إليه. فيما يلي بعض الأمثلة المحددة
نسخة الكود كما يلي:
OX // => 1x سمة التعبير o
OYZ // => 3 Z سمة التعبير OY
س. ["x"] // => 1 كائن O's X
A [1] // => 4 عنصر مع فهرس التعبير A هو 1
A [2] ["1"] // => 6 عنصر مع الفهرس 1 في التعبير A [2]
A [0] .x // => 1: x سمة التعبير A [0]
بغض النظر عن شكل تعبيرات الوصول إلى السمات المستخدمة ، فإن التعبيرات قبل ". و "[" يتم تقييم دائما أولا. إذا كانت نتيجة التقييم خالية أو غير محددة ، فسيقوم التعبير بإلقاء استثناء خطأ في النوع لأنه لا يمكن لأي من هذه القيم أن يحتوي على أي سمات. إذا لم تكن نتيجة العملية كائنًا أو صفيفًا ، فسيقوم JavaScript بتحويله إلى كائن (الفصل 3 ، القسم 6)
على الرغم من أن identifier مكتوبة أكثر بكل بساطة ، تجدر الإشارة إلى أن هذه الطريقة تنطبق فقط على اسم السمة ليتم الوصول إليها وهي معرف قانوني. وتحتاج إلى معرفة اسم السمة للوصول. إذا كان اسم العقار عبارة عن كلمة محفوظة أو تحتوي على مسافات وعلامات علامات الترقيم وهي رقم (لمجموعة) ، فيجب كتابة قوسين مربعة. عندما يكون اسم السمة عبارة عن قيمة مستمدة من مشغل بدلاً من قيمة ثابتة ، يجب كتابة قوسين مربعة. (الفصل 6 ، 2 ، 1 بار)
5. تعبير النقل
تعبير الاحتجاج في JavaScript هو تمثيل بناء الجملة للاتصال (أو تنفيذ) وظيفة أو طريقة. يبدأ بتعبير وظيفة يشير إلى الوظيفة المراد استدعاؤها. يتبع تعبير الوظيفة زوج من الأقواس ، مع قائمة معلمات مفصولة بفاصلة. يمكن أن يكون هناك 0 معلمات أو معلمات متعددة.
F (0) // f هو تعبير دالة: 0 هو تعبير معلمة.
Math.Max (x ، y ، z) //math.max هي وظيفة ؛ X و Y و Z هي معلمات
A.Sort () //a.sort () هي وظيفة لا تحتوي على معلمات.
عندما يتم استدعاء التعبير للتقييم ، احسب أولاً تعبير الوظيفة ، ثم احسب تعبير المعلمة للحصول على مجموعة من قيم المعلمة. إذا كانت قيمة تعبير الوظيفة ليست كائنًا قابلًا للاستدعاء ، فسيتم طرح استثناء خطأ في النوع. ثم يتم تعيين قيم المعلمات للمعلمات الرسمية ، والتي يتم تعريفها عند تحديد الوظيفة. بعد ذلك ، قم بتنفيذ جسم الوظيفة. إذا كانت الوظيفة تستخدم عبارة الإرجاع لإعطاء قيمة إرجاع ، فإن قيمة الإرجاع هذه هي قيمة تعبير الاتصال بأكمله. خلاف ذلك ، فإن قيمة تعبير الاتصال غير محددة. سيتم شرح تفاصيل استدعاء الوظيفة - بما في ذلك عدد تعبيرات المعلمة الرسمية وعدد المعلمات الفعلية في تعريف الوظيفة - بالتفصيل في الفصل 8.
أي تعبير استدعاء يحتوي على زوج من الأقواس والتعبيرات قبل الأقواس اليسرى. إذا كان هذا التعبير عبارة عن تعبير للوصول إلى الخصائص ، فسيتم تسمى هذه المكالمة "دعوة الطريقة". عند تنفيذ جسم وظيفة في مكالمة طريقة ، فإن الكائن والمصفوفة التي يتم الوصول إليها كسمات هي مؤشر هذا في طريقة الاتصال. تتيح هذه الميزة للوظائف (اسمها "طريقة") لاستدعاء كائن المضيف الخاص بهم (المزيد على الفصل 9).
6. تعبير خلق الكائن
يقوم تعبير إنشاء الكائن بإنشاء كائن ويستدعي دالة (مُنشئ) لتهيئة خصائص الكائن. تشبه تعبيرات إنشاء الكائنات تعبيرات استدعاء الوظائف ، باستثناء أن هناك كلمة رئيسية إضافية جديدة قبل تعبيرات إنشاء الكائن:
كائن جديد ()
نقطة جديدة (2،3)
إذا كان تعبير إنشاء الكائن لا يتطلب تمرير أي معلمات إلى المُنشئ ، فيمكن حذف هذا الزوج من الأقواس. سيتم شرح المزيد من تفاصيل المنشئ في الفصل 9
كائن جديد
نقطة جديدة
7. نظرة عامة على المشغلين
يتم استخدام المشغلين في JavaScript لحساب تعبيرات الجدول ، وتعبيرات المقارنة ، والتعبيرات المنطقية ، وتعبيرات المهمة ، إلخ.
تجدر الإشارة إلى أن معظم المشغلين ممثلة بعلامات علامات الترقيم ، مثل الحذف و extremof. سواء أكان مشغلات الكلمات الرئيسية أو العوامل الرمزية ، فإن المشغلين الممثلين هم مشغولون منتظمون ، وبناء الجملة موجز للغاية.
يتم فرز أولوية المشغل التراكمي ، وأولوية المشغل السابق أعلى من أولوية المشغل اللاحق. المشغلين مفصولين عن Huafeng الأفقي لديهم أولويات مختلفة.
يمثل A الطبيعة الملزمة للمشغل.
ل من اليسار إلى اليمين أو ص (من اليمين إلى اليسار)
تمثل قائمة العنوان n عدد المعاملات.
يمثل النوع نوع المعامل المتوقع ، ونوع النتيجة للمشغل (بعد رمز "→")
| المشغلين | تعمل | أ | ن | يكتب |
| ++ | الجبهة/بعد الزيادة | ص | 1 | lval → num |
| - | انخفض قبل وبعد | ص | 1 | lval → num |
| - | ابحث عنك | ص | 1 | num → num |
| + | تحويل إلى أرقام | ص | 1 | num → num |
| ~ | عكس قليلا | ص | 1 | int → int |
| ! | المنطقي غير اللوحي | ص | 1 | Bool → Bool |
| حذف الحذف | حذف السمات | ص | 1 | LVAL → BOOL |
| نوع | اكتشاف نوع التشغيل | ص | 1 | أي → str |
| فارغ | إرجاع قيمة غير محددة | ص | 1 | أي → undef |
| * ، /، ٪ | اضرب وتقسيم للعثور على الباقي | ل | 2 | Num ، num → num |
| +،-- | إضافة ، طرح | ل | 2 | Num ، num → num |
| + | اتصال السلسلة | ل | 2 | str ، str → str → str |
| << | تحول اليسار | ل | 2 | int ، int → int |
| >> | التحول الصحيح | ل | 2 | int ، int → int |
| >>> | حق غير موقّع | ل | 2 | int ، int → int |
| <، <= ،> ،> = | قارن ترتيب الأرقام | ل | 2 | Num ، num → Bool |
| <، <= ،> ،> = | قارن الطلب في الحروف | ل | 2 | Str ، Str → Bool |
| مثيل | اختبار كائن فئة | ل | 2 | OBJ ، Func → Bool |
| في | اختبار ما إذا كانت السمة موجودة | ل | 2 | Str ، OBJ → Bool |
| == | حكم متساو | ل | 2 | أي ، أي → بول |
| ! = | حكم غير راضٍ | ل | 2 | أي ، أي → بول |
| === | تحكم على الصفات | ل | 2 | أي ، أي → بول |
| ! == | القاضي غير الثابت | ل | 2 | أي ، أي → بول |
| & & | bitwise و | ل | 2 | int ، int → int |
| ^ | bitwise xor | ل | 2 | int ، int → int |
| | | bitwise أو | ل | 2 | int ، int → int |
| && | المنطق و | ل | 2 | أي ، أي → أي |
| || | منطقي أو | ل | 2 | أي ، أي → أي |
| ؟: | المشغل الشرطي | ص | 3 | منطقي ، أي ، أي → أي |
| = | مهمة التخصيص المتغير أو سمة الكائن | ص | 2 | Lval ، أي → أي |
*= /= ٪ = += -= & = ^= | = << = >> = >>> = | حساب وتعيين القيم | ص | 2 | Lval ، أي → أي |
| و | تجاهل المعامل الأول ، يعيد المعامل الثاني. | ل | 2 | أي ، أي → أي |
أنا. عدد المعاملات
يمكن تصنيف المشغلين من خلال عدد المعاملات.
معظم المشغلين في JavaScript هم عوامل ثنائية تجمع بين تعبيرين في تعبير أكثر تعقيدًا قليلاً.
يدعم JavaScript أيضًا بعض عوامل Unary التي تقوم بتحويل تعبير إلى تعبير آخر أكثر تعقيدًا قليلاً. المشغل " -" في التعبير -x هو عامل Unary. هو للعثور على قيمة سالبة لـ x.
يدعم JavaScript مشغلًا ثلاثيًا: مشغل الحكم الشرطي "؟:" ، والذي يجمع بين ثلاثة تعبيرات في تعبير واحد
الثاني. نوع المعامل ونوع النتيجة
يمكن استخدام بعض المشغلين لأي نوع من البيانات ، لكنهم ما زالوا يريدون أن يعملوا على بيانات النوع المحدد.
III.LVALUE
يتوقع مشغلي المهام وغيرهم من المشغلين في الجدول نوع Lval المعامل ، Lvalue هو مصطلح قديم. وهذا يعني أن "التعبيرات لا يمكن أن تظهر إلا على الجانب الأيسر من مشغل المهمة". في JavaScript ، تكون المتغيرات وخصائص الكائن وعناصر الصفيف كلها LVALUES. تتيح مواصفات ECMASCRIPT للدالة المدمجة في النطاق بإرجاع LVALUE ، ولكن لا يمكن للوظائف المحددة إرجاع LVALUE.
الثالث. أولوية المشغل
في الجدول أعلاه ، يتم فرز المشغلين المعروفين من ارتفاع إلى منخفض بأولوية ، مع وجود مجموعة من المشغلين داخل كل فاصل أفقي له نفس الأولوية. يتحكم أولوية المشغل في الترتيب الذي يتم فيه تنفيذ المشغلين. يتم دائمًا تنفيذ المشغلين ذوي العالي (أعلى الجدول) أعلى من المشغلين ذوي الأولوية المنخفضة (أسفل الجدول).
انظر التعبير التالي
w = x+y*z ؛
يتمتع مشغل الضرب "*" بأولوية أعلى من الإضافة "+" ، لذلك يتم تنفيذ الضرب أولاً. ثم ، نظرًا لأن مشغل المهمة "=" له أدنى أولوية. لذلك ، يتم تنفيذ عملية المهمة بعد التعبير على اليمين يحسب النتيجة.
يمكن كتابة أولوية المشغل باستخدام أقواس الحديقة. التعبير أعلاه يمكن كتابة مثل هذا.
w = (x + y) * z ؛
تجدر الإشارة إلى أن أولوية تعبيرات الوصول إلى الممتلكات وتعبيرات الاتصال أعلى من جميع المشغلين في الجدول.
typeof my.function [x] (y)
على الرغم من أن TypeOF هو واحد من أعلى مشغلي الأولوية ، إلا أنه يتم تنفيذ TypeOF أيضًا بعد الوصول إلى الممتلكات ومكالمات الوظائف.
في الواقع ، إذا لم تكن متأكدًا حقًا من أولوية المشغل الذي تستخدمه ، فإن أسهل طريقة هي استخدام أقواس الحديقة لفرض ترتيب العمليات. يجب حفظ بعض القواعد المهمة: الضرب والتقسيم أعلى من الإضافة والطرح ، وأولوية عمليات المهمة منخفضة للغاية ، وعادة ما يتم تنفيذها أخيرًا.
iiiiiii.operationality
في هذا القسم ، يوضح العمود A العقيد للمشغل. يشير L إلى المجموعة من اليسار إلى اليمين ، ويشير R إلى المجموعة من اليمين إلى اليسار. يحدد السل ترتيب العمليات في تعبيرات متعددة المشغلات بنفس الأولوية.
على سبيل المثال ، يتم تنفيذ عملية الطرح في مجموعة من اليسار إلى اليمين.
نسخة الكود كما يلي:
W = x - y - z
مثل هذا الرمز:
نسخة الكود كما يلي:
w = ((x - y) - z)
على العكس ، التعبير التالي:
نسخة الكود كما يلي:
x = ~ -y ؛
w = x = y = z ؛
q = a؟ b: c؟ d: e؟ f: g ؛
بالضبط نفس الرمز
نسخة الكود كما يلي:
x = ~ (-y) ؛
w = (x = (y = z)) ؛
س = أ؟ ب: (C؟ D: (E؟ F: G))
لأن مشغلي أحادية ، والواجبات ومشغلي الحالة الثلاثية جميعهم لديهم مجموعة من اليمين إلى اليسار.
iiiiiiiii.operation أمر
تحدد أولوية وربط المشغلين ترتيب العمليات في معادلة المهمة ، ولكنها لا تحدد ترتيب العمليات في عملية حساب تعبيرات الكلمات. تقوم JavaScript دائمًا بحساب التعبيرات بشكل صارم بالترتيب من اليسار إلى اليمين ، على سبيل المثال:
في التعبير w = x+y*z ، سيتم حساب التعبير w أولاً ، ثم سيتم حساب x و y و z ، ثم سيتم ضرب قيم y بواسطة z ، مع إضافة قيمة x. أخيرًا ، يشار إلى المتغير أو السمة المشار إليها من خلال تعبيره W. ستؤدي إضافة شريحة دائرة إلى تعبير إلى تغيير العلاقة بين عمليات الضرب والإضافة والتعيين. لكن الأمر من اليسار إلى اليمين لن يتغير.
8. التعبيرات الحسابية
يغطي هذا القسم مشغلي حساب الحساب ، وكذلك العمليات الحسابية على المعاملات. تعتبر عوامل الضرب والتقسيم والطرح بسيطة للغاية. عملية الإضافة عبارة عن قسم منفصل لأن مشغل الإضافة يمكنه تشغيل سلسلة متسلسلات السلسلة وتحويل نوعها مميز إلى حد ما.
مشغلي الحساب الأساسي هم *، /، ٪ ، +، -. بالإضافة إلى الإضافة +، فإن المشغلين الآخرين بسيطون بشكل خاص. يتم تحويلها فقط إلى أرقام عند الضرورة ، وبعد ذلك يمكنهم العثور على المنتج ، الحاصل ، المتبقي (الوحدة النمطية) والفرق. سيتم تحويل جميع تلك العمليات التي لا يمكن تحويلها إلى أرقام إلى قيم NAN. إذا كان المعامل (أو نتيجة التحويل) قيمة نان ، فإن نتيجة التشغيل الحسابية هي أيضًا نان
يقسم المشغل "/" المعامل الثاني على المعامل الأول ، إذا كنت قد استخدمت لغات البرمجة التي تميز عدد صحيح ونقطة عائمة. ثم عندما تقسم عدد صحيح على عدد صحيح ، فإن النتيجة المرجوة هي أيضًا عدد صحيح. في JavaScript ، جميع الأرقام هي أرقام فاصلة ، ونتيجة عمليات التقسيم هي أيضًا أنواع نقطة عائمة. على سبيل المثال ، تكون نتيجة 5/2 هي 2.5 ، وليس 2. نتيجة العملية مع المقسوم 0 هي اللانهاية الإيجابية أو اللانهاية السلبية. ونتيجة 0/0 هي نان. لن تقوم كل هذه العمليات بالإبلاغ عن أخطاء.
يقوم المشغل "٪" بحساب معامل المعامل الأول إلى المعامل الثاني ، وبعبارة أخرى ، يتم تقسيم المعامل الأول على بقية المعامل الثاني. يتوافق رمز النتيجة مع رمز الماوس الأول للعملية (مقسمة). على سبيل المثال ، نتيجة 5 ٪ 2 هي 1 ، و -5 ٪ 2 هي -1.
عادة ما تكون معاملات المشغل الباقي أعداد صحيحة ، لكنها مناسبة أيضًا لأرقام الفاصلة العائمة. 6.5 ٪ 2.1 النتيجة هي 0.2. (0.1999999999999999973)
أنا. عامل "+"
يمكن لمشغل الإضافة الثنائية "+" إضافة رقمين أو عمليات متسلسلة السلسلة:
نسخة الكود كما يلي:
1+2 // => 3
"Hello" " +" " +" هناك "// =>" مرحبا هناك "
"1"+"2" // => "12"
عندما يكون كل من المعاملات أرقام أو سلاسل ، تكون نتائج الحساب واضحة. ومع ذلك ، بالنسبة للحالات الأخرى ، يلزم بعض التحويل اللازم. ويعتمد سلوك المشغل على نتيجة تحويل النوع. من الناحية الفنية ، فإن سلوك مشغل الإضافة هو:
إذا كان المعامل كائنًا ، فسيتابع الكائن قاعدة تحويل الكائن إلى القيمة الأصلية لقيمة الفئة الأصلية (انظر الفصل 3 ، القسم 8 ، 3). DATE ينفذ التحويل على طريقة الكائن TOSTRING () ، في حين أن الكائنات الأخرى تنفذ التحويل عبر طريقة valueof () (إذا كانت طريقة valueof () تُرجع قيمة بدائية). نظرًا لأن معظم الكائنات لا تحتوي على طريقة ValueOF () المتاحة ، فسيستخدمون طريقة ToString () لأداء الزحف
بعد تحويل الكائن إلى القيمة الأصلية ، إذا كانت إحدى العمليات عبارة عن سلسلة ، فسيتم تحويل المعامل الآخر أيضًا إلى سلسلة. ثم قم بتسلسل السلسلة.
خلاف ذلك ، سيتم تحويل كلا المعاملين إلى أرقام (أو NAN) ثم إضافة.
فيما يلي بعض الأمثلة
نسخة الكود كما يلي:
1 + 2 // => 3 إضافة
"1" + "2" // => "12" اتصال سلسلة
"1" + 2 // => "12" يتم تحويل الأرقام إلى سلاسل ومسلسل
1 + {} // => "1 [كائن كائن]": يتم تحويل الكائن إلى سلسلة ثم يتم تنفيذ سلسلة سلسلة.
True + True // => 2 يتم تحويل القيمة المنطقية إلى رقم وإضافة
2 + NULL // => 2 تم تحويل الفارغ إلى 0 وأداء إضافة
2 + غير محدد // => يتحول NAN غير المحدد إلى NAN للإضافة
أخيرًا ، من المهم ملاحظة. عند استخدام عملية الإشارة بالإضافة إلى الأوتار ، ينبغي النظر في تأثير الإضافة على ترتيب العمليات. بمعنى أن نتيجة العملية تعتمد على ترتيب تشغيل المشغل ، على سبيل المثال
نسخة الكود كما يلي:
1 + 2 + "Bmice" // => "3 Bmice"
1 + (2 + "Bmice") => "12bmice"
الثاني. مشغل أحادي
يعمل مشغل Unary على معامل منفصل. وتوليد قيمة جديدة. في JavaScript ، يكون للمشغلين Unary أولوية عالية وكلهم مصممين يمينًا. يصف هذا القسم مشغلي UNARY (+،-، ++ و-) ، وعند الضرورة ، يقومون بتحويل العمليات إلى أرقام. تجدر الإشارة إلى أن + - هو مشغل أحادي ، وهو أيضًا مشغل ثنائي.
إضافة yuan+
يقوم مشغل إضافة UNARY بتحويل رقم المعامل إلى رقم (أو NAN) ويعيد الرقم المحول. إذا كان المعامل نفسه رقمًا ، فسيتم إرجاع الرقم مباشرة.
طرح واحد يوان-
عندما تكون الإشارة مشغل أحادي ، فإنها ستحول المعامل إلى رقم حسب الحاجة ، ثم تغيير رمز نتيجة العملية.
زيادة ++
زيادة مشغل "++" إلى زيادة (+1) المعامل ، والمعامل هو lvalue (متغير ، عنصر الصفيف ، أو سمة الكائن). يقوم المشغل بتحويل المعاملات إلى الأرقام. ثم أضف 1 إلى الرقم وإعادة تعيين القيمة بعد إضافة 1 إلى متغير أو عنصر الصفيف أو سمة الكائن.
تقوم عملية زيادة ++ بإرجاع القيمة التي تعتمد على موضعها على المعامل.
عندما يكون المشغل قبل رقم المعامل ، يطلق عليه المشغل "المسبق" ، الذي يحسب بشكل تدريجي المعامل ويعيد القيمة المحسوبة.
عندما يكون المشغل بعد المعامل ، يطلق عليه مشغل "ما بعد المنشور". إنه يقوم بحسابات تدريجية على المعامل ، ولكنه يعيد القيمة غير المخصصة التي يتم استخدامها للحسابات الإضافية. يحب
var i = 1 ، j = ++ i // قيم i و j كلاهما 2
var i = 1 ، j = i ++ ؛ // أنا 2 ، J هو 1
تجدر الإشارة إلى أن مجموع ++ x = x+1 هو نفسه بالضبط. لا يقوم مشغل "++" بعمليات سلسلة السلسلة أبدًا. سيقوم دائمًا بتحويل المعامل إلى رقم وزيادةه بمقدار 1. إذا كانت X هي السلسلة "1" ، فإن نتيجة ++ X هي الرقم 2 ، و X+1 هي السلسلة "11"
العمليات المتناقصة والزيادة هي نفسها ، والتي تحول المعاملات إلى صفيف ثم يتم طرحها بمقدار 1.
ثالثا. مشغل بت
يمكن لمشغل BIT إجراء عمليات منخفضة المستوى على البيانات الثنائية التي تمثلها الأرقام. على الرغم من أنها ليست عمليات رياضية خالصة تقليدية ، إلا أنها تم تصنيفها أيضًا هنا كمشغلين حسابيين لأنها تعمل على عمليات الأنواع الرقمية وأرقام الإرجاع. هؤلاء المشغلين ليسوا شائعين في جافا سكريبت. (غير موصوف هنا ، يرجى استخدام Baidu للحصول على التفاصيل ~-~)
9. التعبيرات العلائقية
يصف هذا القسم مشغلي علاقات JavaScript. تُستخدم المشغلين العلائقيين لاختبار العلاقة بين قيمتين (المساواة ، أقل من أو "سمات") وإرجاع صحيح وكاذب وفقًا لما إذا كانت العلاقة موجودة. تعيد التعبيرات العلائقية دائمًا قيمة منطقية ، وعادة ما تستخدم التعبيرات العلائقية في إذا كانت أو للبيانات (الفصل 5) للتحكم في عملية تنفيذ البرنامج.
ستتحدث الأقسام القليلة التالية عن المساواة والعمليات غير المتكافئة ومشغلي المقارنة وشخصيتي العلاقة الأخرى في JavaScript
أنا المساواة والمشغلين غير المتكافئين
يتم استخدام المشغلين "==" و "===" لمقارنة ما إذا كانت قيمتان متساوية ، ويسمح المشغلان للمشغلين من أي نوع. إرجاع صحيح إذا كان على قدم المساواة ، وإلا عودة خطأ. يُطلق على "===" أيضًا مشغل المساواة الصارم (يُطلق عليه أحيانًا مشغل الهوية) ، والذي يتم استخدامه لاكتشاف ما إذا كانت المعاملتين متساوية تمامًا. يسمى عامل "==" مشغل المساواة. يتم استخدامه لاكتشاف ما إذا كانت المعاملتين متساوية. تعريف المساواة هنا فضفاض ويسمح بتحويل النوع.
يدعم JavaScript مشغلات "=" ، "==" ، "===" ، يجب أن تفهم الاختلافات بين عوامل (المهمة ، المساواة ، الهوية). وكن حذرًا عند البرمجة. من أجل تقليل الارتباك ، "=" "يجب أن يسمى" GET OR ENDIGE "،" == "" يجب أن يسمى "متساوٍ" ، و "===" يجب أن يسمى "متساوٍ تمامًا".
قواعد "! =" و "! ==" المشغلين "==" ، عكس "===" المشغل ، و "!" هو غير المنطقي غير العاملة. نسميه "! =" ، "! ==" غير متكافئ وليس متساويًا تمامًا.
مقارنة كائنات JavaScript هي مقارنة للمراجع ، وليس مقارنة للقيم. الأشياء وأنفسهم متساوية ، لكنها لا تساوي الناس والأشياء. إذا كان لدى كائنين نفس عدد السمات ، نفس أسماء السمات والقيم ، فهي لا تزال غير متكافئة. عناصر الصفيف في الموضع المقابل متساوية ومصفوفتين غير متكافئتين أيضًا.
يقوم مشغل المساواة الصارم "===" أولاً بحساب قيمة المعامل ، ثم قارن هاتين القيمتين. لا يوجد تحويل في عملية المقارنة.
إذا كان النوعان من القيمة لا يريدون أن يكونا متماثلين ، فهما لا يساويان
إذا كانت كلتا القيمتين فارغة أو غير محددة ، فهي ليست متساوية
إذا كانت كلتا القيمتين صحيحة أو خاطئة ، فهي متساوية
إذا كانت إحدى القيم هي NAN ، أو كلاهما نان ، فهي ليست متساوية ، و NAN والقيم الأخرى ليست متساوية ، بما في ذلك نفسها.
إذا كانت قيمتان أرقامًا ومتساوية ، فهي متساوية. إذا كانت القيمة 0 وكانت القيمة -0 ، فهي متساوية أيضًا.
إذا كانت القيمتين هما سلاسل وأرقام من 16 رقمًا (انظر الفصل 3 ، 2) الواردة في البتات المقابلة متساوية تمامًا ، فهي متساوية. إذا كان طولها أو محتوىها مختلفًا ، فهي ليست متساوية. قد يكون للسلاسل نفس الوظيفة تمامًا والأحرف المعروضة هي نفسها ، ولكن لها قيم 16 بت غير مشفرة. لا تقوم JavaScript بتحويلات قياسية على Unicode ، لذا فإن مثل هذه السلاسل ليست متساوية بالمقارنة مع مشغلي "===" و "==". string.localeCompare () في الجزء الثالث يوفر طريقة أخرى لمقارنة السلاسل.
إذا كانت قيمتان مرجعيتان تشير إلى نفس الكائن أو الصفيف أو الوظيفة ، فهي متساوية. إذا كانت الإشارة إلى كائنات مختلفة ، فهي عدم المساواة ، على الرغم من أن الكائنين لهما نفس الخصائص بالضبط.
يشبه مشغل المساواة "==" مشغل الهوية ، ولكن لم تتم مقارنة مشغل المساواة بشكل صارم. إذا لم يكن الرقمان من نفس النوع ، فإن مشغل المساواة يحاول القيام ببعض تحويل النوع ثم يقارن.
إذا كانت العمليتان متماثلين ، فإن قواعد المقارنة لمشغلي المساواة أعلاه هي نفسها. إذا كانت متساوية تمامًا ، فإن نتائج المقارنة متساوية. إذا لم تكن متساوية تمامًا ، فإن نتائج المقارنة ليست متساوية.
إذا كان نوعي التشغيل مختلفان ، فسوف يعتبرها المشغل المساواة "==" مساواة. سيتبع اكتشاف المساواة القواعد التالية وتحويلات الكتابة:
إذا كان النوع فارغًا ودع الآخر يكون غير محدد ، فسيكون ذلك متساويًا
إذا كانت قيمة واحدة هي رقم والآخر عبارة عن سلسلة ، فقم بتحويل السلسلة إلى رقم أولاً ، ثم استخدم القيمة المحولة للمقارنة.
إذا كانت القيمة صحيحة ، فسيتم تحويلها إلى 1 ثم مقارنة. إذا كانت القيمة خاطئة ، يتم تحويلها إلى 0 ومقارنتها.
إذا كانت قيمة واحدة هي كائن والآخر عبارة عن رقم أو سلسلة ، فاستخدم قواعد التحويل للطريقة في الفصل 3 ، القسم 8 ، 3 لتحويل الكائن إلى القيمة الأصلية ثم قارنها. يتم تحويل الكائن إلى القيمة الأصلية من خلال طريقة ToString () أو طريقة ValueOF (). تحاول الفئات المدمجة في قلب لغة JavaScript أولاً استخدام ValueOf () ثم حاول استخدام ToString (). بالإضافة إلى فئة التاريخ ، لا يمكن تحويل فئة التاريخ إلا من خلال ToString (). يتم تحويل الكائنات التي ليست في قلب لغة JavaScript إلى قيم أصلية من خلال الطرق المحددة في التنفيذ.
المقارنات بين الأنواع الأخرى ليست متساوية
هنا مثال صغير على الحكم المتساوي
"1" == صحيح
نتيجة هذا التعبير صحيحة ، مما يشير إلى أن نتائج المقارنة لأنواع مختلفة تمامًا من القيم متساوية. يتم تحويل القيمة المنطقية أولاً إلى الرقم 1 ثم يتم إجراء المقارنة. بعد ذلك ، يتم تحويل السلسلة "1" أيضًا إلى الرقم 1 ، لأن قيم الرقمين متساوية ، وبالتالي فإن النتيجة صحيحة.
الثاني. مشغل المقارنة
أقل من (<)
إذا كان المعامل الأول أصغر من المعامل الثاني ، فإن نتيجة التشغيل "<" صحيحة ، وإلا فهي خاطئة
أقل من أو يساوي (<=)
أكبر من (>)
أكبر من أو يساوي (> =)
.... (لا توجد مقدمة مفصلة للمعنى)
قد تكون معاملات مشغل المقارنة من أي نوع. ومع ذلك ، يمكن فقط للأرقام والسلاسل أن تؤدي في الواقع مشغلي المقارنة ، لذلك سيتم تحويل المعاملات التي ليست أرقام والسلاسل. قواعد تحويل النوع هي كما يلي:
إذا كان المعامل كائنًا ، فسيتم تحويله إلى القيمة الأصلية وفقًا لقواعد التحويل الموضحة في القسم 3 ، القسم 8 ، 3: إذا كانت ValueOF () تقوم بإرجاع قيمة بدائية ، فاستخدم هذه القيمة الأصلية مباشرة. خلاف ذلك ، استخدم نتيجة التحويل لـ ToString () للمقارنة.
بعد التحويل إلى القيمة الأصلية ، إذا كانت كلتا المعاملتين سلاسل ، فسيتم مقارنة السلاسل بترتيب الأبجدية. "ترتيب الأبجدية" المذكور هنا هو ترتيب فهرس أحرف Unicode 16 بت التي تشكل السلاسل.
بعد تحويل الكائن إلى القيمة الأصلية ، إذا لم يكن المعامل على الأقل سلسلة ، فإن كلا المعاملين ستقارن قيم الأرقام. 0 و -0 متساوين. أي رقم آخر في جدار Infinty كبير (باستثناء Infinty نفسه) ، -الأثرية أصغر من أي رقم (باستثناء نفسه). إذا كان المعامل (أو تحويله) نان ، فإن حرف المقارنة يعيد دائمًا خطأ
بالنسبة لمشغلي الرقم والسلسلة ، يختلف سلوك مشغل علامة Plus عن مشغل المقارنة. السابق يفضل الأوتار ويؤدي عمليات تسلسل السلسلة إذا كانت إحدى معاملاتها عبارة عن سلسلة. يفضل المشغلون المقارنون الأرقام فقط عندما يكون كل من المعاملات سلاسل سلسلة. عندها فقط سيتم تنفيذ مقارنة السلسلة.
نسخة الكود كما يلي:
1 + 2 // => 3 إضافة ، والنتيجة هي 3
"1" + "2" // connect string ، النتيجة هي "12"
"1" + 2 // Connect String ، يتم تحويل 2 إلى "2" ، النتيجة هي "12"
11 <3 // مقارنة الأرقام ، والنتيجة صحيحة
"11" <"3" // مقارنات الوقوف ، والنتيجة صحيحة
"11" <3 // مقارنة الأرقام ، "11" يتم تحويلها إلى 11 ، والنتيجة صحيحة
"واحد" <3 // مقارنة الرقم ، "واحد" يتم تحويله إلى نان ، والنتيجة خاطئة
أخيرًا ، تجدر الإشارة إلى أنه عند الحكم على المساواة ، لا يعتمد المشغلون "<=" و "> =" على مشغل المساواة وقواعد مقارنة عملية المساواة الصارمة. على العكس من ذلك ، فإن المشغل Zhi الذي أقل من أو يساوي ببساطة "ليس أكبر من" ، في حين أن العملية التي تكون أكبر من أو تساوي فقط "لا يقل عن". مع استثناء واحد فقط ، عندما يكون المعامل (بعد تحويله) هو NAN ، سيعود جميع مشغلي المقارنة الأربعة إلى fasle.
III.IN المشغل
يريد المشغل في المعامل الأيسر أن يكون سلسلة أو يمكن تحويله إلى سلسلة ، ويأمل أن يكون كائنًا إلى اليمين. إذا كان للكائن الموجود على اليمين اسم سمة يسمى قيمة المعامل اليسرى ، فإن التعبير يرجع صحيحًا. على سبيل المثال
نسخة الكود كما يلي:
var point = {
X: 1 ،
Y: 1
} // تحديد كائن
"x" في point // => true يحتوي الكائن على خاصية تسمى x
"z" في point // => false الكائن لا يوجد اسم z سمة
"tostring" في النقطة // => يرث الكائن الحقيقي طريقة tostring
var data = [7 ، 8 ، 8]
"0" في البيانات // => True تحتوي الصفيف على 0
1 في البيانات // => رقم تحويل حقيقي إلى سلسلة
3 في البيانات // => لا يوجد عنصر مع فهرس 3
IIII.Instanceof Operator
يريد عامل التشغيل من المشغل الأيسر أن يكون كائنًا ويشير المعامل الأيمن إلى فئة الكائن. إذا كان الكائن الموجود على اليسار هو مثيل للفئة على اليمين ، فإن التعبير يعود صحيحًا ؛ انها مسؤولة عن العودة كاذبة. الفصل 9 سيتحدث عن ذلك. يتم تعريف فئات كائنات JavaScript عن طريق تهيئة مُنشئاتها. وبهذه الطريقة ، يجب أن يكون المعامل الصحيح لمثلة من وظيفة. على سبيل المثال:
نسخة الكود كما يلي:
var d = new Date () ؛ // بناء كائن جديد
d dateof date ؛ // نتيجة الحساب صحيحة ، يتم إنشاء D حسب التاريخ ()
d instanceof Object //计算结果为true ,所有的对象都是Object的实例
d instanceof Number //计算结果为false,d不是一个Number对象
var a = [1,2,3] //数组直接量创建数组
a instanceof Array //计算结果true a为数组
a instanceof Object //true 所有的数组都是对象
a instanceof RegExp //fasle 数组不是正则表达式
需要注意的是,所有对象都是Object的实例。当通过instanceof盘对一个对象是否为一个类的实例的时候,这个判断也叫“父类”(superclass)的检测,如果instanceof的左侧操作对象不是对象的话,instanceof返回false。如果右侧操作不是函数,则抛出类型错误的异常。
为了理解instanceof运算符是如何工作的,必须首先理解“原型类”(prototype chain),原型链作为javascript的继承机制,将在6章2节2小节详细描述。
为了计算表达式o instanceof f ,javascript笔仙首先计算f.prototyoe,然后在原型链中查询o,如果找到,那么o是f(或者f的父类)的一个实例,那么返回true。反之false
10.逻辑表达式
逻辑运算符"&&"、“||”、“!”是对操作进行布尔算术运算,经常和关系运算符一起配合使用,逻辑运算符将多个关系表达式组合起来组成一个更复杂的表达式。
أنا. Logic and
"&&"运算符可以从三个不同的层次进行理解。最简单一层理解是,当操作数都是布尔值是,“&&”对两个布尔值执行布尔与(AND)操作,只有在第一个操作数和第二个操作数都是true的时候,它才返回true.如果其中有一个操作数为false.则它返回false.
"&&"长用来连接两个关系表达式
x == 0 && y == 0; //只有在x和y都是0时,才返回true
关系表达式总是返回true或false,因此当这样使用的时候,“&&”本身也返回true或false。关系运算符的优先级要比"&&"(和“||”)要高,因此类似这种表达式可以放心地书写,而不用补充园括号。
"&&"操作数并不一定是布尔值,回想一下,有些值是可以当做“真值”和“假值”的。(如3章3节,假值是:false null undefined 0 -0 NaN和"",所有和其它的值包括所有的对象都是真值)。对“&&”第二层理解是,“&&”是可以对真值和假值进行布尔与(AND)操作。如果两个操作数都是真值的,则那么返回一个真值;否则,至少一个操作数是假值的。javascript中在任何使用布尔值的地方的时候,表达式语句都会将其当做真值或假值来对待,因此实际上“&&”并不总是返回true和false.但也并无大碍。
需要注意的是,上文提到了运算符返回“真值”和“假值”,但并没说说明这个“真值”或者“假值”到底是什么值,为此我们深入讨论对“&&”第三层的理解。运算符首先计算左操作数的值,即首先计算“&&”左侧的表达式,如果计算结果是假值,那么整个表达式的结果一定是假值,因此“&&”这时简单的返回左操作的值,而并不会对右边的操作数进行计算。
نسخة الكود كما يلي:
var o = {
x: 1
} ؛
var p = null;
o && ox; //=>1 : 1:0是真值,因此返回值是ox
p && px //= null :p是假值,因此将其返回,而并不计算px
这对于理解“&&”可能不计算右操作数的情况至关重要,在上述代码中,变量P的值是null,而如果计算px的话则会抛出一个异常错误,因此,只有p为真值(不能是null或undefined)的情况下才计算px
"&&"的行为有时候被称为“短路”(short circuiting),我们经常能看到很多代码利用了这一也行来有条件的执行代码。例如下面的两条代码是等价的
نسخة الكود كما يلي:
if (a == b) stop(); //只有a==b时才能调运stop()
(a == b) && stop(); //同上
一般来讲,当“&&”右侧的表达式具有副作用的时候(赋值,递增,递减和函数调用表达式)要格外小心。因为这些带有副作用的表达式的执行时候,依赖于左操作鼠的计算结果。
尽管“&&”可以按照第二层和第三层的理解进行一些复杂的表达式运算,但大多数的情况下,“&&”仅用来对真值和假值的做布尔计算。
الثاني. Logical or (||)
"||"运算符对两个操作数做布尔或(OR)运算。如果其中一个为真值,则返回真值,两个操作数都为假值,返回假值。
尽管“||”运算符大多情况下只是做简单的布尔或(OR)运算,和“&&”一样,也具备一些更复杂的行为,它首先计算第一个操作数的值,也就是说回首先计算左侧的表达式,如果计算结果为真,则返回真值,否则,再计算第二个值。
和“&&”一样,用于应该避免右操作数包含一些具有副作用的表达式,除非你目地明确在右侧使用带副作用的表达式,而有可能不会计算右侧的表达式。
这个运算符最常用的方式是用来从一组备选的表达中选取第一个真值的表达式。
نسخة الكود كما يلي:
//如果max_width已经定义了,则直接使用它。赋值在preferences对象中查找max_width
//如果没有定义它,则使用一个写死的常量。
var max =max_width || preferences.max_windth || 500;
这种贯用法通常在函数体内,用来给参数提供默认值。
نسخة الكود كما يلي:
//将o成功的属性复制到p中,并返回p
function copy(o, p) {
p = p || {}; //如果向参数p没有传入任何对象,则使用一个新创建对象。
//函数体内的主逻辑
iii.逻辑非(!)
ال "!" operator is a unary operator that is placed before a separate operand. Its purpose is to invert the boolean value of the operand.
Unlike the "&&" and "||" operators, the "!" operator first converts its operands into a Boolean value (see the Rules in Chapter 3), and then inverses the Boolean value. إنه، "!" always returns true and false. Furthermore, the Boolean value of a value can be obtained by using two logical non-operations: (!!x, refer to Section 8, Section 2, Chapter 3)
“!”具有很高的优先级,并且和操作数紧密的绑在一起,如果希望对p && q,则需要园括号!(p && q)。如下代码:
نسخة الكود كما يلي:
!(p && q) === !p || !q
!(p || q) === !p && !q
对于p和q取任何值,这两个表达式永远成立。
11.赋值表达式
javascript使用"="运算符给变量或者属性来赋值,例如:
نسخة الكود كما يلي:
i = 0 //将变量i设置为0
ox = 1 //将对象o的属性x 设置为1
“=”运算符希望它的左操作数为一个左值:一个变量或者对象属性(或数组元素),它的右操作鼠可以是任意的类型的任意值。赋值表达式的值就是右操作数的值。赋值表达式的副作用是,右操作数的值赋值给左侧的变量或对象属性。这样的话,后续对这个变量和对象的属性的引用都将得到这个值。
尽管赋值表达式的值非常简单,但有时候会看到一些复杂表达式包含赋值表达式的情况。例如:将赋值和检测操作放在一个表达式中:
نسخة الكود كما يلي:
(a = b) == 0
如果这样的话,应该清楚地知道"="和"=="区别!,需要注意的是,“=”有非常低的优先级,通常在一个较长的表达式中用到一条赋值语句时,需要补充园括号以保障正确的运算顺序。
赋值操作符的结合性是从右至左,也就是说,一个表达式中出现了多个赋值运算符,运算顺序也从右至左,因此,可以通过以下方式对多个变量赋值。
نسخة الكود كما يلي:
i=j=k=0; //把三个变量初始化为0
带操作的赋值运算:
除了常规的赋值运算外,javascript还支持需要其他的赋值运算符,这些运算符将赋值运算符合其他的运算符连接起来。提供一种更为快捷的运算方式。例如+=运算符执行的是加法运算符和赋值操作,下面的表达式:
total += salaes_tax;
和下面的表达式等价的
total = total + salaes_tax
运算符“+=”可以作用于数字或字符串,如果其操作是数字,它将执行加法运算和赋值操作;如果是字符串,他就执行字符串的连接和赋值操作。
此类型的运算符还包括,"-=","*=","&="等,如下表赋值运算符
运算符示例等价于
+=a+=ba=a+b
-=a-=ba=ab
*=a*=ba=a*b
/=a/=ba=a/b
%=a%=ba=a%b
<<=a<<=ba=a<<b
>>=a>>=ba=a>>b
>>>=a>>>=ba=a>>>b
&=a&=ba=a&b
|=a|=ba=a|b
^=a^=ba=a^b
大多数情况下,表达式为
a op =b
这里的op代表一个运算符,这个表达式等价于
a =a op b
在第一行中,表达式a计算了一次,在第二行中,表达式a计算了两次。
只有a包含具有副作用的表达式(比如函数调用和赋值操作)的时候,两者才不等价。如下两个表达式不等价
نسخة الكود كما يلي:
data[i++] *= 2;
data[i++] = data[i++] * 2
12.表达式计算
和很多解释性语言一样,javascript同样可以解释运行由javascript源代码组成的字符串,并产生一个值。javascript通过全局函数eval()来完成这个工作。
eval("3+2") //=>5
动态判断源代码中的字符串是一种强大语言的特性,几乎没有必要在实际中应用。如果你使用了eval(),你应该仔细考虑真的需要它。
下面降价eval()基础用法,并介绍两种严格使用它的方法,从代码优化的角度来讲,这两种方法对原有的代码影响是最小的。
i.eval (eval()是一个函数,但由于它已经被当做运算符来对待了。)
eval()只有一个参数,如果传入的参数不是字符串,它直接返回这个参数。如果参数是字符串,它会把字符串当成javascript进行编译(parse),如果编译失败则抛出一个语法错误(SyntaxError)。如果编译成功,则开始执行这段代码,并返回字符串中最后一个表达式或语句的值,如果最后一个表达式没有语句或者值,则最终返回undefined。如果字符串抛出一个异常,这个异常把该调用的传给eval()
关于eveal()最重要的是,它使用了调用它的变量作用域环境,也就是说,它查找变量的值和定义新变量和函数的操作和局部的代码作用域中的代码一样。如果一个函数定义了一个局部变量x,然后调用了eval("x"),它会返回局部变量的值。如果它调用eval("x=1"),它会改变局部变量的值。如果函数调用了eval("var y=3;")它声明一个新的局部变量y。同样的,一个函数可以通过如下代码声明一个局部函数:
eval("function f(){return x+1;}");
如果最顶层的代码中调用了eval()。当然它会作用于全局变量和全局函数。
الثاني. Global eval()
eval()具有改变局部变量的能力,这对javascript优化器来说,是一个很大的问题,然而作为一种权宜之计,javascript征对那行调用了eval()函数所做的优化并不多。但当脚本定义了一个别名,并且用令一个名称来调用它,javascript解释器又如何工作呢,为了javascript解释器更加简化。ECMAScipt3标准规定了任何解释器都不允许对eval()赋予别名。如果eval()使用别的别名来调用的话,则会抛出EvalError异常。
实际上,大多数的实现并不是这样做的。当通过别名调用时,eval()会将其字符串当成顶层的全局代码来执行。执行代码可能会定义新的全局变量和全局函数。执行的代码可能会定义新的全局变量和全局函数,或者给全局变量赋值。但却不能修改或修改主调函数中的局部变量,因此这不会影响到函数内的代码优化。
ECMAScript5是反对使用EvalError的,并且规范了eval()的行为。“直接的eval”,当直接使用非限定的“eval”名称,来调用eval()函数时,它总共是在它的上下文作用域内支线。其它间接调用则使用全局函数为其上下文作用域。并且无法读、写、定义局部变量和函数。下面有一段代码实例:
نسخة الكود كما يلي:
var geval = eval; //使用别名调用eval将是全局eval
var x = "global",
y = "global"; //两个全局变量
function f() { //函数内执行的局部eval
var x = "local" //定于局部变量
eval("x += 'changed';"); //直接eval更改了局部变量的
إرجاع x ؛ //Return the changed local variable
}
function g() { //这个函数执行了全局eval
var y = "local" //定义了局部变量
geval("y += 'changed';"); //间接改变了局部变量的值
return y; //返回未更改的局部变量
}
console.log(f(), x); //更改了局部变量,输出local changed global
console.log(g(), y); //更改了全局变量,输出local globalchanged
13.其它运算符。
javascript支持很多其它各种各样的运算符。
أنا. Conditional operator (?:)
The conditional operator is the only ternary operator in javascript. Usually this operator is written as "?:". This operator has the third operand, the first operand is before "?", and the second operand is between "?" و ":". The third operand is long after ":", e.g.
x > 0 ? x : -x; //求x的绝对值
条件运算符的操作数可以是任意类型。第一个操作数当成布尔值,如果它是真值,那么将计算第二个操作数,并返回计算结果。赋值如果第一个值操作数是假值,那么将计算第三个操作数。并返回计算结果。第二个和第三个操作数总会计算其中之一。不可能两者同时进行。其实使用if语句也达到同样的效果(5.4.1),“?:”运算符只是提供了一种简写形式。这里是一个"?:"的典型使用场景,判断一个变量是否有定义,如果有定义则使用它,如果无定义,则使用一个默认值。
نسخة الكود كما يلي:
grett = "hello" + (username ? username : "three");
和以下的代码是等价的,但上面的更加简洁
نسخة الكود كما يلي:
grett = "hello";
if (username)
grett += username;
آخر
grett + "three"
ii.typeof()运算符
typeof是一元运算符,放在单个操作数前面,操作数可以是任何类型,返回值表示操作类型的一个字符串。
نسخة الكود كما يلي:
x __ typeof x
undefined __ "undefined"
null __ "object"
ture或false __"boolean"
任意数字或NaN __ "Number"
任意字符串__ "String"
任意函数__ "function"
任意内容对象(非函数)__ "object"
任意宿主对象__ 由编译器各自实现的字符串,但不是"undefined" "boolean" "number" "string"
typeof最常用的用法写在表达式中们就像这样
(typeof value == "string") ? "" + value + "":value;
typeof运算符同样在swith语句中(5.4.3)非常有用,需要注意的是,typeof运算可以带上园括号。这样让typeof看起来像一个函数名,而非关键字
typeof(i)
iii.delete运算符
delete是一元操作符,它用来删除对象的属性或者数组的元素。就像赋值、递增、递减运算符一样。delete也是具有副作用的。它是用来做删除操作的。不是用来返回一个值的。
نسخة الكود كما يلي:
var o = {
x: 1,
y: 2
}
delete ox;
"x" in o; //=>false
var a = [1, 2, 3];
delete a[2]; // 删除数组中最后一个元素
2 in a; //=> false 元素2已经在数组中不存在了
a.length; //=>3,注意,数组长度并没有改变,尽管上一行删除了这个元素,但删除操作留下了一个洞。实际上并没有修改数组的长度,因此a的长度仍然为3
需要注意的是,删除属性或删除数组元素不仅仅设置了一个undefined值,当删除一个属性时,这个属性不复存在。读取一个不存在的值将会返回undefined.关于delete删除还有严格模式下的一些情况,需要学习的人自己试验,这里给一些例子。
نسخة الكود كما يلي:
var o = {x: 1,y: 2};
delete ox; //删除一个对象属性,返回true
typeof ox; //属性不存在,返回"undefined"
delete ox; //删除不存在的属性,返回true;
delete o; //不能删除通过var关键字声明的变量,返回false
delete 1; //参数不是一个左值。
this.x = 1;// 给全局定义一个属性,这里没有使用var
delete x ; //试图删除它,在非严格模式下返回true
//在严格模式下回抛出异常,这时使用"delete this.x"来代替
x; //运行时出错,没有定义x
6章第三节还有关于delete的讨论。
iii.void运算符。
void是一元运算符,在出现操作数之前,操作数可以是任何类型。这个运算符并不是经常使用:操作数会照常计算,但会忽略计算结果并返回undefined。由于void会忽略操作数的值,因此在操作数具有副作用时使用void来程序更有意义。
这个最常用的带客户端url.在url写带有副作用的表达式,而void则让浏览器不显示在这个表达式的运算结果。
نسخة الكود كما يلي:
<a href="javascript:void window.open();">new</a>
iiii.逗号运算符。(,)
逗号运算符是二元运算符,它的操作数可以是任意类型。它首先计算左操作数,然后计算右操作数。
نسخة الكود كما يلي:
i = 0, j = 1, k = 2;
它和下面的代码基本上等价的
أنا = 0 ؛ j = 1; k = 2;
总是会计算左侧的表达式,但计算结果忽略掉,也就是说,只有左侧表达式具有副作用,才会使用逗号运算让代码变得更通畅。逗号运算符最常用的场景是for循环中,这个for循环通常有多个循环变量。
نسخة الكود كما يلي:
//for循环中的第一个逗号是var语句的一部分
//第二个逗号是逗号运算符
//它将两个表达式(i++和j++)放在一条(for循环中)语句中
for (var i = 0, j = 10; i < j; i++, j--);
console.log(i + j);