الفرق بين المراجعتين لصفحة: «JavaScript/Symbol»
لا ملخص تعديل |
ط استبدال النص - '\[\[تصنيف:(.*)\]\]' ب'{{SUBPAGENAME}}' |
||
سطر 202: | سطر 202: | ||
* مسودة المعيار [https://tc39.github.io/ecma262/#sec-symbol-objects ECMAScript Latest Draft]. | * مسودة المعيار [https://tc39.github.io/ecma262/#sec-symbol-objects ECMAScript Latest Draft]. | ||
* معيار [http://www.ecma-international.org/ecma-262/6.0/#sec-symbol-objects ECMAScript 2015 (6th Edition)]. | * معيار [http://www.ecma-international.org/ecma-262/6.0/#sec-symbol-objects ECMAScript 2015 (6th Edition)]. | ||
[[تصنيف:JavaScript]] | [[تصنيف:JavaScript|{{SUBPAGENAME}}]] | ||
[[تصنيف:JavaScript Global Objects]] | [[تصنيف:JavaScript Global Objects|{{SUBPAGENAME}}]] | ||
[[تصنيف:JavaScript Symbol]] | [[تصنيف:JavaScript Symbol|{{SUBPAGENAME}}]] |
مراجعة 15:37، 28 يناير 2018
الدالة Symbol()
تُعيد قيمةً من النوع symbol
، وتملك هذه الدالة خاصيات ساكنة (static properties) ودوال ساكنة (التي تُستخدَم للوصول إلى سجل الرموز العام، أي global symbol registry، ويسمى أيضًا بالمصطلح symbol table)؛ وهذه الدالة تحاول التشبه بالدوال البانية للكائنات، لكنها ليست دالةً بانيةً لعدم القدرة على استخدام المعامل new
معها كما في new Symbol()
.
كل رمز (symbol) مُعاد من الدالة Symbol()
هو رمزٌ فريد؛ ويمكن أن يُستخدَم كمُعرِّف (identifier) لخاصيات الكائنات، وهذا هو الغرض الرئيسي من هذا النوع من البيانات. لاحظ أنَّ نوع البيانات symbol
هو نوع بيانات أوليّ (primitive data type).
البنية العامة
Symbol([description])
description
وسيط اختياري، وهو وصفٌ نصيٌّ للرمز الذي يمكن أن يُستخدَم لأغراض تنقيح الأخطاء (debugging) لكن ليس للوصول إلى الرمز نفسه.
الوصف
لإنشاء رمز أوليّ (primitive symbol)، فيمكنك استخدام الدالة Symbol()
مع -أو دون- تمرير سلسلة نصية اختيارية إليها:
var sym1 = Symbol();
var sym2 = Symbol('foo');
var sym3 = Symbol('foo');
الشيفرة السابقة تُنشِئ ثلاثة رموز جديدة، لاحظ أنَّ الدالة Symbol("foo")
لا تحوِّل السلسلة النصية "foo"
إلى رمز، وإنما ستُنشِئ رمزًا جديدًا في كل مرة تستدعى فيها.
Symbol('foo') === Symbol('foo'); // false
لاحظ أنَّ استخدام الدالة Symbol
مع المعامل new
سيؤدي إلى رمي TypeError
:
var sym = new Symbol(); // TypeError
ما سبق يمنع المبرمجين من إنشاء كائن Symbol
لتغليف القيم الأوليّة بدلًا من إنشاء رمز جديد، وقد يُفاجئ هذا السلوك البعض لأنَّ إنشاء كائنات تُغلِّف قيمًا أوليّةً هو أمرٌ مسموحٌ في JavaScript (ومثال ذلك استخدام new Boolean
، و new String
و new Number
).
لكن إذا أردتَ إنشاء كائن يُغلِّف قيمةً أوليةً من النوع Symbol
، فيمكنك استخدام الدالة البانية Object()
:
var sym = Symbol('foo');
typeof sym; // "symbol"
var symObj = Object(sym);
typeof symObj; // "object"
الرموز المشتركة في سجل الرموز العام
استخدام الدالة Symbol()
كما سبق لن يؤدي إلى إنشاء رمز عام الذي يكون متاحًا في كامل تطبيقك. فلإنشاء رموز تتوافر في أكثر من ملف فاستخدم الدالة Symbol.for()
و Symbol.keyFor()
لضبط والحصول على الرموز من سجل الرموز العام (global symbol registry).
العثور على الخاصيات الرمزية في أحد الكائنات
الدالة Object.getOwnPropertySymbols()
تُعيد مصفوفةً تحتوي على جميع الرموز المستخدم في الكائن، لاحظ أنَّ جميع الكائنات تُهيِّئ دون وجود خاصيات رمزية فيها، لذا ستكون هذه المصفوفة فارغةً ما لم تضبط خاصيات رمزية على الكائن.
الخاصيات
Symbol.length
قيمة الخاصية length
، وهي 0.
Symbol.prototype
تمثِّل هذه الخاصية الكائن prototype للدالة Symbol
.
الرموز المعروفة
إضافة إلى الرموز التي نُعرِّفها باستخدام الدالة Symbol
، تملك JavaScript رموزًا مضمَّنة فيها التي تُمثِّل سلوك اللغة الداخلي، والتي لم تكن متاحةً للمطورين في إصدار ECMAScript 5 وما قبله؛ ويمكن الوصول إلى الرموز المعروفة (well-known symbols) عبر الخاصيات تالية الذكر.
رموز الدوران
Symbol.iterator
دالة تُعيد iterator الافتراضي لأحد الكائنات، الذي يُستخدَم من حلقة for...of
.
Symbol.asyncIterator
هذه الدالة تُعيد AsyncIterator
الافتراضي لأحد الكائنات، الذي يُستخدَم من حلقة for await of
. لاحظ أنَّ هذه الخاصية تجريبية حتى الآن.
رموز التعابير النمطية
Symbol.match
دالة تُطابَق مع سلسلة نصية، وتُستخدَم أيضًا لتحديد إذا كان بالإمكان استخدام الكائن كتعبير نمطي. وتُستخدَم من الدالة String.prototype.match()
.
Symbol.replace
هذا الرمز المعروف يُحدِّد الدالة التي ستستبدل جزءًا من سلسلة نصية؛ وهذه الدالة ستُستدعى من الدالة String.prototype.replace()
.
لمزيدٍ من المعلومات، راجع صفحة RegExp.prototype[@@replace]()
و String.prototype.replace()
.
Symbol.search
هذا الرمز المعروف يُحدِّد الدالة التي ستعيد فهرسًا (index) ضمن سلسلة نصية الذي يُطابِق التعبير النمطي؛ وهذه الدالة ستُستدعى من الدالة String.prototype.search()
.
لمزيدٍ من المعلومات، راجع صفحة RegExp.prototype[@@search]()
و String.prototype.search()
.
Symbol.split
هذا الرمز المعروف يُحدِّد الدالة التي ستقسم سلسلة نصية في الفهارس (indexes) التي تُطابِق تعبيرًا نمطيًا؛ وهذه الدالة ستُستدعى من الدالة String.prototype.split()
.
لمزيدٍ من المعلومات، راجع صفحة RegExp.prototype[@@split]()
و String.prototype.split()
.
الرموز الأخرى
Symbol.hasInstance
دالة تُحدِّد إذا كانت الدالة البانية تعترف على أحد الكائنات على أنَّه كائنٌ مُنشَأٌ منها. وتُستخدَم من المعامل instanceof
؛ ويمكن تخصيص سلوك المعامل instanceof
باستخدام هذا الرمز.
يمكنك تخصيص سلوك المعامل instanceof
كما في المثال الآتي:
class MyArray {
static [Symbol.hasInstance](instance) {
return Array.isArray(instance);
}
}
console.log([] instanceof MyArray); // true
Symbol.isConcatSpreadable
قيمة منطقية تُحدِّد إذا كان يجب «تسطيح» (flatten) الكائن إلى عناصر مصفوفة. ويستخدم هذا الرمز من الدالة Array.prototype.concat()
.
Symbol.species
دالة تُستخدَم لإنشاء كائنات مشتقة.
Symbol.toPrimitive
دالة تُستخدَم لتحويل الكائن إلى قيمة أوليّة.
Symbol.toStringTag
سلسلة نصية تُستخدَم في الوصف الافتراضي للكائن، ويستخدم هذا الرمز من الدالة Object.prototype.toString()
.
الدوال
Symbol.for(key)
البحث عن رموز لها المفتاح المعيّن وإعادتها إن وجدت؛ وإلا فسينُشَأ رمزٌ جديد في سجل الرموز العام له هذا المفتاح.
Symbol.keyFor(sym)
الحصول على مفتاح الرمز المعطي من سجل الرموز العام.
الكائن prototype
جميع الرموز ترث من الكائن Symbol.prototype
.
الخاصيات
Symbol.prototype.constructor
تُحديد الدالة التي ستُنشِئ كائن prototype للرمز، وهي الدالة Symbol
افتراضيًا.
الدوال
Symbol.prototype.toString()
إعادة سلسلة نصية تحتوي على وصف الرمز، وهي تُعيد تعريف الدالة Object.prototype.toString()
.
Symbol.prototype.valueOf()
إعادة القيمة الأولية لأحد كائنات Symbol
، وهي تُعيد تعريف الدالة Object.prototype.valueOf()
.
Symbol.prototype[@@toPrimitive]
تحويل الكائن Symbol
إلى قيمة أوليّة.
أمثلة
استخدام المعامل typeof
مع الرموز
يمكن استخدام المعامل typeof
للتعرف على الرموز:
typeof Symbol() === 'symbol'
typeof Symbol('foo') === 'symbol'
typeof Symbol.iterator === 'symbol'
تحويل الرموز
هذه بعض الأمور التي يجب أخذها بالحسبان عند محاولة تحويل قيم الرموز إلى أنواع بيانات أخرى:
- عند محاولة تحويل رمز إلى رقم (مثلًا:
+sym
أوsym | 0
) فسيرمى الخطأTypeError
. - عند استخدام معامل المساواة (دون مطابقة) مثل
Object(sym) == sym
فستُعاد القيمةtrue
. - التعبير البرمجي
Symbol("foo") + "bar"
سيرمي الخطأTypeError
، وهذا يمنع إنشاء خاصيات لها مفاتيح نصية مشتقة من رموز. - استخدام الدالة
String(sym)
تماثل استخدام الدالةSymbol.prototype.toString()
عند التعامل مع الرموز، لكن لاحظ أنَّ الدالةnew String(sym)
سترمي الخطأTypeError
.
الرموز وحلقة التكرار for...in
لا يمكن المرور على الرموز باستخدام حلقة التكرار for...in
، أضف إلى ذلك أنَّ الدالة Object.getOwnPropertyNames()
لا تُعيد الخاصيات الرمزية، إذ يجب استخدام الدالة Object.getOwnPropertySymbols()
لإعادة الخاصيات الرمزية:
var obj = {};
obj[Symbol('a')] = 'a';
obj[Symbol.for('b')] = 'b';
obj['c'] = 'c';
obj.d = 'd';
for (var i in obj) {
console.log(i); // "c" "d"
}
الرموز والدالة JSON.stringify()
سيتم تجاهل الخاصيات الرمزية تمامًا عند استخدام الدالة JSON.stringify()
:
JSON.stringify({[Symbol('foo')]: 'foo'});
// '{}'
تغليف الرموز
عند استخدام كائن مُغلِّف لرمز كمفتاح لخاصيةٍ ما، فسيحوّل الكائن إلى الرمز الذي يُغلِّفُه:
var sym = Symbol('foo');
var obj = {[sym]: 1};
obj[sym]; // 1
obj[Object(sym)]; // 1
دعم المتصفحات
الميزة | Chrome | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
الدعم الأساسي | 38 | 36 | غير مدعومة | 25 | 9 |
على الرغم من أنَّ متصفح IE لا يدعم هذه الميزة، لكن متصفح Edge يدعمها بدءًا من الإصدار 12.
مصادر ومواصفات
- مسودة المعيار ECMAScript Latest Draft.
- معيار ECMAScript 2015 (6th Edition).