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

مصادر ومواصفات