مهيئ الكائنات في JavaScript
يمكن تهيئة الكائنات باستخدام new Object()
أو الدالة Object.create()
أو باستخدام الشكل المختصرة (initializer notation). إنَّ مُهيّئ الكائنات هو قائمة فيها «صفر» زوج أو أكثر من أسماء الخاصيات مع القيم المرتبطة بها، مفصولةٌ بفواصل، ويحيط بها قوسين معقوفين {}
.
البنية العامة
var o = {};
var o = {a: 'foo', b: 42, c: {}};
var a = 'foo', b = 42, c = {};
var o = {a: a, b: b, c: c};
var o = {
property: function ([parameters]) {},
get property() {},
set property(value) {}
};
البنى الجديدة في ECMAScript 2015
رجاءً ارجع إلى جدول التوافقية لترى ما هو دعم هذه البنى، إذ إنَّ هذه البنى ستعطي أخطاءً في المتصفحات غير الداعمة لها.
// أسماء الخاصيات المختصرة
var a = 'foo', b = 42, c = {};
var o = {a, b, c};
// أسماء الدوال المختصرة
var o = {
property([parameters]) {}
};
// أسماء الخاصيات المحسوبة
var prop = 'foo';
var o = {
[prop]: 'hey',
['b' + 'ar']: 'there'
};
الوصف
مُهيّئ الكائنات هو تعبيرٌ (expression) يصف عملية تهيئة الكائنات من النوع Object
؛ والكائنات تتألف من خاصيات (properties) التي تُستخدَم لوصف الكائن، وقيم تلك الخاصيات يمكن أن تكون إما قيمًا أوليّةً (primitive) أو كائنات أخرى.
إنشاء الكائنات
يمكن إنشاء كائن فارغ دون خاصيات مرتبطة به كما يلي:
var object = {};
لكن ميزة استخدام الشكل المختصر هو تمكين إنشاء كائنات لها خاصيات مُعرَّفة داخل القوسين المعقوفين، إذ يمكن ذكر الخاصيات وقيمها على الشكل key: value
ويُفصَل بين تلك الأزواج بفاصلة ,
.
الشيفرة الآتية تُنشِئ كائنًا له ثلاث خاصيات أسماؤها هي foo
و age
و baz
، وقيم تلك الخاصيات هي السلسلة النصية "bar"
والعدد 42
وكائن آخر (على التوالي وبالترتيب).
var object = {
foo: 'bar',
age: 42,
baz: {myProp: 12}
}
الوصول إلى الخاصيات
بعد إنشاء الكائن، فربما ترغب بقراءة الخاصيات أو تغييرها، ويمكن الوصول إلى خاصيات الكائن عبر طريقة النقطة (dot notation) أو طريقة الأقواس (bracket notation)، راجع صفحة الوصول إلى الخاصيات لمزيدٍ من المعلومات.
object.foo; // "bar"
object['age']; // 42
object.foo = 'baz';
تعريف خاصيات جديدة
صحيحٌ أننا نستطيع إضافة الخاصيات إلى الكائن عند تعريفه، لكن ستحتاج في غالب الأحيان إلى إضافة خاصيات جديدة تابعة لأحد الكائنات:
var a = 'foo',
b = 42,
c = {};
var o = {
a: a,
b: b,
c: c
};
أما في ECMAScript 2015، فهنالك شكلٌ مختصرٌ لفعل نفس ما سبق:
var a = 'foo',
b = 42,
c = {};
// أسماء الخاصيات المختصرة
var o = {a, b, c};
// بصيغة مختلفة
console.log((o.a === {a}.a)); // true
أسماء الخاصيات المكررة
عند استخدام نفس الاسم لأكثر من خاصية، فستُعتمَد قيمة آخر خاصية:
var a = {x: 1, x: 2};
console.log(a); // {x: 2}
تعريف الدوال
يمكن أن تكون إحدى خاصيات الكائن دالةً أو getter أو setter:
var o = {
property: function ([parameters]) {},
get property() {},
set property(value) {}
};
هنالك شكلٌ مختصرٌ جديدٌ في ECMAScript 2015، الذي أصبحت فيه الكلمة المحجوزة function
غير ضرورية:
// أسماء الدوال المختصرة
var o = {
property([parameters]) {},
*generator() {}
};
أسماء الخاصيات المحسوبة
بدءًا من ECMAScript 2015 أصبح شكل تعريف الكائنات يدعم استخدام أسماء محسوبة للخاصيات، وهذا يعني أنَّنا نستطيع وضع تعبير (expression) ضمن قوسين مربعين []
وستُحسَب قيمة التعبير وتُستخدَم اسمًا للخاصية. ويمكنك استخدام نفس الشكل لقراءة وضبط خاصيات كائن موجود مسبقًا:
// أسماء الخاصيات المحسوبة
var i = 0;
var a = {
['foo' + ++i]: i,
['foo' + ++i]: i,
['foo' + ++i]: i
};
console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3
var param = 'size';
var config = {
[param]: 12,
['mobile' + param.charAt(0).toUpperCase() + param.slice(1)]: 4
};
console.log(config); // {size: 12, mobileSize: 4}
تعديل كائن prototype
إذا عرّفنا خاصيةً بالشكل __proto__: value
أو الشكل "__proto__": value
فلن تُنشَأ خاصيةٌ باسم __proto__
وإنما سيتغير الكائن prototype
إذا كانت القيمة المُسنَدَة إليه هي كائن أو null
.
var obj1 = {};
assert(Object.getPrototypeOf(obj1) === Object.prototype);
var obj2 = {__proto__: null};
assert(Object.getPrototypeOf(obj2) === null);
var protoObj = {};
var obj3 = {'__proto__': protoObj};
assert(Object.getPrototypeOf(obj3) === protoObj);
var obj4 = {__proto__: 'not an object or null'};
assert(Object.getPrototypeOf(obj4) === Object.prototype);
assert(!obj4.hasOwnProperty('__proto__'));
لا يُسمَح إلا بتغيير كائن prototype
إلا مرةً واحدةً عند تعريف الكائن، وإلا فسيرمى خطأ SyntaxError
.
الفرق بين تعريف الكائنات وصيغة JSON
الصيغة المختصرة لتعريف الكائنات لا تُماثل صيغة JSON (اختصارٌ للعبارة JavaScript Object Notation)؛ فعلى الرغم من أنّهما تبدوان شبيهتين ببعضهما بعضًا، لكن هنالك بعض الاختلافات بينهما:
- لا تسمح صيغة JSON إلا بتعريف الخاصيات باستخدام الشكل
"property": value
، ويجب أن يحاط اسم الخاصية بعلامتَي اقتباس مزدوجتين، ولا يمكن استخدام الأشكال المختصرة لتعريف الخاصيات. - يُسمَح باستخدام السلاسل النصية والأرقام والمصفوفات والقيمة
true
وfalse
وnull
وكائنات JSON الأخرى فقط في صيغة JSON. - لا يمكن إسناد دالة إلى إحدى الخاصيات في صيغة JSON.
- الكائنات مثل الكائن
Date
ستصبح سلاسل نصية بعد استدعاء الدالةJSON.parse()
. - الدالة
JSON.parse()
سترفض أسماء الخاصيات المحسوبة وسترمي خطأً.
دعم المتصفحات
الميزة | Chrome | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
الدعم الأساسي | نعم | نعم | نعم | نعم | نعم |
أسماء الخاصيات المحسوبة | 47 | 34 | غير مدعومة | 34 | 8 |
أسماء الخاصيات والدوال المختصرة | 47 | 34 | غير مدعومة | 34 | 9 |
على النقيض من متصفح IE، يدعم متصفح Edge كل هذه الميزات.
مصادر ومواصفات
- مسودة المعيار ECMAScript Latest Draft.
- معيار ECMAScript 2015 (6th Edition).
- معيار ECMAScript 5.1.
- معيار ECMAScript 1st Edition .