Object.defineProperties()
الدالة Object.defineProperties()
تُعرِّف خاصياتٍ جديدةً على كائنٍ مباشرةً، أو تُعدِّل خاصياتٍ موجودةً مسبقًا في كائنٍ ثم تُعيد هذا الكائن.
البنية العامة
Object.defineProperties(obj, props)
obj
الكائن الذي نريد تعريف الخاصيات فيه أو تعديلها.
props
كائنٌ فيه خاصياتٌ تابعةٌ له وقابلةٌ للإحصاء تُحدِّد واصفات الخاصيات (property descriptors) التي ستُضاف إلى الكائن أو تُعدِّله والتي سترتبط بأسماء الخاصيات. وهنالك نوعان للواصفات: واصفات البيانات (data descriptors) وواصفات الوصول (accessor descriptors)، راجع صفحة الدالة Object.defineProperty()
لمزيدٍ من التفاصيل.
واصفات البيانات وواصفات الوصول هما كائنات، ويتشاركان المفاتيح المطلوبة الآتية:
configurable
: إذا كانت قيمة هذا المفتاح هيtrue
فيمكن تعديل واصف الخاصية (وليس قيمة الخاصية) ويمكن حذف الخاصية من الكائن. القيمة الافتراضية هيfalse
.enumerable
: إذا كانت قيمة هذا المفتاح هيtrue
فستظهر هذه الخاصية عند إحصاء خاصيات (enumeration) الكائن. القيمة الافتراضية هيfalse
.
يمكن أن تتواجد المفاتيح الاختيارية الآتية في واصفات البيانات:
value
: تحديد القيمة المرتبطة مع الخاصية، ويمكن أن تكون أيّ قيمة مسموحة في JavaScript (مثل الأعداد أو الدوال أو الكائنات ...إلخ.). القيمة الافتراضية هيundefined
.writable
: إذا كانت قيمة هذا المفتاح هيtrue
فسيمكن تعديل القيمة المرتبطة بهذا الخاصية باستخدام معاملات الإسناد. القيمة الافتراضية هيfalse
.
يمكن أن تتواجد المفاتيح الاختيارية الآتية في واصفات الوصول:
get
: الدالة التي ستُعدّ كدالة getter لهذا الخاصية، أو القيمةundefined
إذا لم تكن هنالك دالة getter مرتبطة مع هذه الخاصية؛ القيمة التي ستُعيدها هذه الدالة ستُستخدَم كقيمة للخاصية. القيمة الافتراضية هيundefined
.set
: الدالة التي ستُعدّ كدالة setter لهذا الخاصية، أو القيمةundefined
إذا لم تكن هنالك دالة setter مرتبطة مع هذه الخاصية؛ تقبل هذه الدالة وسيطًا واحدًا هو القيمة الجديدة التي حاول المستخدم إسنادها إلى هذه الخاصية. القيمة الافتراضية هيundefined
.
القيمة المعادة
الكائن الذي مُرِّرَ إلى الدالة.
الوصف
الدالة Object.defineProperties()
تُعرِّف جميع الخاصيات على الكائن obj
، والتي تكون تابعة للكائن props
(ويجب أن تكون قابلةً للإحصاء أيضًا).
أمثلة
مثال عن تعريف خاصيتين property1
و property2
على الكائن obj
، وإحدى تلك الخاصيتين قابلةٌ للكتابة (عبر إسناد القيمة true
للمفتاح writable
) وأخرى غير قابلة للكتابة (عبر إسناد القيمة false
للمفتاح writable
):
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
// ...
});
تعويض نقص دعم المتصفحات
بفرض أنَّ بيئة التشغيل غير مُعدَّلة، إذ تُشير فيها جميع الأسماء والخاصيات إلى قيمها الابتدائية، فالدالة الآتية تكافئ الدالة Object.defineProperties()
تقريبًا:
function defineProperties(obj, properties) {
function convertToDescriptor(desc) {
function hasProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
function isCallable(v) {
// NB: modify as necessary if other values than functions are callable.
return typeof v === 'function';
}
if (typeof desc !== 'object' || desc === null)
throw new TypeError('bad desc');
var d = {};
if (hasProperty(desc, 'enumerable'))
d.enumerable = !!desc.enumerable;
if (hasProperty(desc, 'configurable'))
d.configurable = !!desc.configurable;
if (hasProperty(desc, 'value'))
d.value = desc.value;
if (hasProperty(desc, 'writable'))
d.writable = !!desc.writable;
if (hasProperty(desc, 'get')) {
var g = desc.get;
if (!isCallable(g) && typeof g !== 'undefined')
throw new TypeError('bad get');
d.get = g;
}
if (hasProperty(desc, 'set')) {
var s = desc.set;
if (!isCallable(s) && typeof s !== 'undefined')
throw new TypeError('bad set');
d.set = s;
}
if (('get' in d || 'set' in d) && ('value' in d || 'writable' in d))
throw new TypeError('identity-confused descriptor');
return d;
}
if (typeof obj !== 'object' || obj === null)
throw new TypeError('bad obj');
properties = Object(properties);
var keys = Object.keys(properties);
var descs = [];
for (var i = 0; i < keys.length; i++)
descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);
for (var i = 0; i < descs.length; i++)
Object.defineProperty(obj, descs[i][0], descs[i][1]);
return obj;
}
دعم المتصفحات
الميزة | Chrome | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
الدعم الأساسي | 5 | 4 | 9 | 11.6 | 5 |
مصادر ومواصفات
- مسودة المعيار ECMAScript Latest Draft.
- معيار ECMAScript 2015 (6th Edition).
- معيار ECMAScript 5.1.