واصف السمة هو مفهوم جديد تم إضافته في ES5 ، وتتمثل وظيفته في إضافة المزيد من التحكم إلى خصائص الكائن.
Object.DefineProperty
لدراسة واصفات السمات ، يجب علينا أولاً التحدث عن طريقة الكائن. الغرض من هذه الطريقة هو تحديد خصائص جديدة للكائن أو تعديل الخصائص الموجودة. النموذج الأولي على النحو التالي:
نسخة الكود كما يلي:
Object.DefineProperty (OBJ ، Prop ، Descriptor)
مثال على الاستخدام:
نسخة الكود كما يلي:
var obj = {} ؛
Object.DefineProperty (obj ، 'attr' ، {value: 1}) ؛
يضيف الرمز أعلاه سمة تسمى attr إلى كائن OBJ ، بقيمة 1. تعادل:
نسخة الكود كما يلي:
var obj = {} ؛
obj.attr = 1 ؛
بالمقارنة ، يبدو أن كتابة object.defineProperty أكثر تعقيدًا. ومع ذلك ، يكمن سره الأكبر في معلمته الثالثة.
واصف البيانات
على افتراض أننا نريد أن تكون attr سمة للقراءة فقط ، يمكننا إضافة واصف البيانات القابل للكتابة:
نسخة الكود كما يلي:
var obj = {} ؛
Object.DefineProperty (obj ، 'attr' ، {
القيمة: 1 ،
قابلة للكتابة: خطأ
}) ؛
console.log (obj.attr) ؛
obj.attr = 2 ؛ // يفشل
console.log (obj.attr) ؛
قم بتنفيذ البرنامج أعلاه وستجد أن قيمة ATTR المطبوعة مرتين هي 1 ، مما يعني أن كتابة السمة فشلت. ومع ذلك ، فإن هذه النتيجة ستكون غير مفهومة بعض الشيء ، لأن تنفيذ بيان المهمة لا يحتوي على أي استثناءات ، لكنه يفشل. فقط تخيل أنه في حالة حدوث مثل هذه المشكلة في رمز blockbuster ، سيكون من الصعب استكشافها. في الواقع ، طالما تم تشغيل الكود في وضع صارم ، سيتم إنشاء استثناء:
نسخة الكود كما يلي:
"استخدام صارم" ؛ // أدخل الوضع الصارم
var obj = {} ؛
Object.DefineProperty (obj ، 'attr' ، {
القيمة: 1 ،
قابلة للكتابة: خطأ
}) ؛
obj.attr = 2 ؛ // رمي الاستثناء
دعونا نلقي نظرة على واصف بيانات آخر ، والذي يمكنه التحكم في ما إذا كان يمكن تعداد السمة. إذا قمت ببساطة بتحديد خاصية ، فيمكن تعداد هذه الخاصية في ... في الحلقة:
نسخة الكود كما يلي:
var obj = {} ؛
obj.attr = 1 ؛
لـ (var i in obj) {console.log (obj [i]) ؛ }
يمكن التعداد "إخفاء "ه:
var obj = {} ؛
Object.DefineProperty (obj ، 'attr' ، {
القيمة: 1 ،
التعداد: خطأ
}) ؛
لـ (var i in obj) {console.log (obj [i]) ؛ }
قم بتنفيذ الكود أعلاه وستجد أن وحدة التحكم لا تخرج شيئًا ، لأنه لا يمكن تعداد سمة ATTART في هذا الوقت.
بعد قولي هذا ، قد يكون لديك سؤال: هل يمكن تعديل واصف السمة؟ على سبيل المثال ، هل يمكن تعريف خاصية للقراءة فقط على أنها قابلة للكتابة مرة أخرى؟ في الواقع ، يعتمد هذا على تكوين واصف بيانات آخر ، والذي يمكنه التحكم في ما إذا كان يمكن تغيير واصف السمة.
نسخة الكود كما يلي:
var obj = {} ؛
Object.DefineProperty (obj ، 'attr' ، {
القيمة: 1 ،
قابلة للكتابة: خطأ ،
قابل للتكوين: صحيح
}) ؛
Object.DefineProperty (obj ، 'attr' ، {
قابل للكتابة: صحيح
}) ؛
obj.attr = 2 ؛
يعرّف الرمز أعلاه أولاً attr على أنه سمة للقراءة فقط ، ثم يعيد تعريفه على أنه قابل للكتابة. لذا فإن الكتابة إلى attr ناجحة.
واصف الوصول
يشبه واصف الوصول مع الإكسسور GET/SET في الكائنات الموجهة.
نسخة الكود كما يلي:
var obj = {} ؛
Object.DefineProperty (obj ، 'attr' ، {
SET: function (val) {this._attr = math.max (0 ، val) ؛ } ،
الحصول على: function () {return this._attr ؛ }
}) ؛
obj.attr = -1 ؛
console.log (obj.attr) ؛ // 0
في الكود أعلاه ، يصبح الوصول إلى ATTR في الواقع الوصول إلى _ATTR ، ويقتصر الحد الأدنى على القيمة 0 في وظيفة SET.
احصل على واصف السمة
المذكورة أعلاه هي كل واصفات السمات ، إذن كيفية الحصول على واصفات المجموعة؟ Object.GetOwnPropertyDescriptor يمكنه القيام بذلك.
نسخة الكود كما يلي:
var obj = {} ؛
Object.DefineProperty (obj ، 'attr' ، {
القيمة: 1 ،
قابلة للكتابة: خطأ ،
قابل للتكوين: صحيح
}) ؛
var desc = object.getownPropertyDescriptor (obj ، 'attr') ؛
console.dir (desc) ؛
السيطرة على الكائن
تعمل الكائن.
Object.PreventExtensions يمكن أن تمنع الكائنات من وجود خصائص جديدة:
نسخة الكود كما يلي:
var obj = {} ؛
obj.attr = 1 ؛
Object.PreventExtensions (OBJ) ؛
obj.attr2 = 2 ؛ //يفشل
يمكن أن يجعل الكائن eseal قيم خاصية الكائن فقط لتعديلها (إذا كانت الخاصية للقراءة فقط ، حتى لا يمكن تعديل قيم الخصائص):
نسخة الكود كما يلي:
var obj = {} ؛
obj.attr = 1 ؛
Object.seal (OBJ) ؛
obj.attr = 1.5 ؛
حذف obj.attr ؛ // يفشل
يمكن أن يجعل الكائن .
نسخة الكود كما يلي:
var obj = {} ؛
obj.attr = 1 ؛
Object.freeze (OBJ) ؛
obj.attr = 1.5 ؛ // يفشل
obj.attr2 = 2 ؛ //يفشل
ثم قد تسأل مرة أخرى ، كيف يمكنك معرفة ما إذا كان قد تم منع كائن ما ، أو ختم أو تجميد؟ الجواب هو استدعاء Object.isextenseBly و Object.issealed و Object.isfrozen على التوالي. استخدام هذه الوظائف الثلاث بسيط نسبيًا ولم يعد مرهقًا.
بشكل عام ، يمكن التحكم في الكائن بشكل صارم من خلال واصفات السمات ويتم تعزيز دقة منطق البرنامج. العيب الوحيد هو أن ES5 يتم تنفيذها بشكل أساسي في IE9 (لا يدعم IE9 الوضع الصارم بعد). بالنظر إلى أن حصة IE8 المحلية لا تزال عالية نسبيًا ، لا يمكن استخدام هذه المجموعة من الأشياء إلا في متصفحات الهاتف المحمول و Node.js.