المعامل delete في JavaScript

من موسوعة حسوب

المعامل delete يحذف خاصيةً من كائن.

البنية العامة

delete expression

إذ يجب أن تكون نتيجة التعبير expression هي مرجعية إلى خاصية من خاصيات الكائن، مثلًا:

delete object.property
delete object['property']

object

اسم الكائن، أو تعبير نتيجته هي إشارة إلى كائنٍ ما.

property

اسم الخاصية التي نريد حذفها.

القيمة المعادة

القيمة true لكل الحالات إلا إذا كانت الخاصية غير قابلة للضبط (non-configurable property)، وفي هذه الحالة ستُعاد القيمة false في النمط non-strict.

الاستثناءات

سيُرمى SyntaxError في نمط strict إذا كانت الخاصية غير قابلةً للضبط (non-configurable property).

الوصف

على النقيض من الاعتقادات الشائعة، المعامل delete ليس له علاقة بتحرير الذاكرة، وإنما وظيفة المعامل delete هي حذف خاصية معيّنة من الكائن، وسيعيد القيمة true إذا نجح بذلك، والقيمة false فيما عدا ذلك؛ لكن من المهم أن نضع الحالات الآتية في الحسبان:

  • إذا كانت الخاصية التي تحاول حذفها ليست موجودةً، فسيعيد المعامل delete القيمة true ولن يكون له أيّ أثر.
  • إذا كانت هنالك خاصية لها نفس اسم الخاصية التي نحاول حذفها في سلسلة prototype فسيَستخدمُ الكائنُ تلك الخاصية (أي بعبارةٍ أخرى: المعامل delete سيؤثر على الخاصيات التابعة للكائن مباشرةً فقط).
  • أيّة خاصية صُرِّحَ عنها باستخدام var لا يمكن أن تُحذَف من المجال العام أو من مجال الدالة.
    • وبالتالي لا يمكن استخدام المعامل delete لحذف أيّة دوال من المجال العام (سواءً عُرِّفَت عبر تعابير تعريف الدوال أو بالتصريح عنها).
    • أما الدوال التي تكون جزءًا من أحد الكائنات (باستثناء الكائن العام) فيمكن حذفها باستخدام المعامل delete.
  • أيّة خاصية صُرِّح عنها باستخدام let أو const لا يمكن حذفها من المجال الذي عُرِّفت فيها.
  • لا يمكن أيّة خاصيات غير قابلة للضبط (non-configurable property)، وهذا يتضمن خاصيات الكائنات المُضمنَّة في اللغة مثل Math و Array و Object، والخاصيات التي أُنشِئت على أنها غير قابلة للضبط عبر الدالة Object.defineProperty()‎.

الشيفرة الآتية تعطي مثالًا بسيطًا عن استخدام المعامل delete:

var Employee = {
  age: 28,
  name: 'abc',
  designation: 'developer'
}

console.log(delete Employee.name);     // true
console.log(delete Employee.age);      // true

// محاولة حذف خاصية غير موجودة
console.log(delete Employee.salary);   // true

الخاصيات غير القابلة للضبط

عند تحديد أنَّ الخاصية غير قابلة للضبط (non-configurable) فلن يكون للمعامل delete أي أثر، وسيُعيد القيمة false، وسيرمي SyntaxError في نمط Strict.

var Employee = {};
Object.defineProperty(Employee, 'name', {configurable: false});

console.log(delete Employee.name);  // returns false

لاحظ أنَّ var و let و const تُنشِئ خاصيات غير قابلة للضبط ولا يمكن حذفها مع المعامل delete:

var nameOther = 'XYZ';

// يمكننا الوصول إلى خاصية تابعة للكائن العام كما يلي
Object.getOwnPropertyDescriptor(window, 'nameOther');  

// output: Object {value: "XYZ", 
//                  writable: true, 
//                  enumerable: true,
//                  configurable: false}

// لاحظ أنَّ الخاصية nameOther غير قابلة للضبط
// ذلك لأنَّها قد أضيفت عبر الكلمة المحجوزة var

delete nameOther; // false

ستؤدي الشيفرة السابقة إلى رمي SyntaxError في نمط strict.

نمط Strict

سيؤدي استخدام المعامل delete على مرجعية مباشرة إلى متغير أو وسيط دالة أو اسم دالة إلى رمي SyntaxError وذلك إذا كان نمط strict مُفعلًا.

نذكِّر أنَّ أيّ متغير مُعرَّف عبر var سيكون غير قابلٍ للضبط؛ ففي المثال الآتي سيكون المتغير salary غير قابلٍ للضبط ولا يمكن حذفه، وسيُعيد المعامل delete القيمة false وذلك لأنه في نمط non-strict:

function Employee() { 
  delete salary;
  var salary;
}

Employee();

سنجرِّب الآن المثال نفسه لكن في نمط strict، فبدلًا من إعادة القيمة false فسيرمى SyntaxError:

"use strict";

function Employee() {
  delete salary;  // SyntaxError
  var salary;        
}

وبشكلٍ مشابه، إذا حاولنا حذف دالة تابعة للكائن العام في نمط strict فسيرمى الخطأ SyntaxError:

function DemoFunction() {
  // ...
}

delete DemoFunction; // SyntaxError

أمثلة

سنُنشِئ في المثال الآتي خاصيةً تابعةً للكائن العام باسم adminName، وسنُنشِئ المتغير empCount باستخدام var وسيكون خاصيةً غير قابلة للضبط في الكائن العام، ثم ستُننِشئ كائنًا باسم EmployeeDetails:

// إنشاء خاصية في الكائن العام
adminName = 'xyz';            

// إنشاء خاصية غير قابلة للضبط في الكائن العام
var empCount = 43;

EmployeeDetails = {
  name: 'xyz',
  age: 5,
  designation: 'Developer'
};

لمّا كانت الخاصية adminName تابعةً للكائن العام وغير مُنشأة باستخدام var، فهي خاصيةٌ قابلةٌ للضبط ويمكن حذفها، وذلك على النقيض من الخاصية empCount؛ لاحظ أنَّ بالإمكان استخدام المعامل delete لحذف خاصيات أحد الكائنات التي أنشأنها (EmployeeDetails)، وسيُعيد القيمة true حتى لو لم تكن الخاصيةُ موجودةً:

delete adminName; // true

// تذكر أنَّ هذه الخاصية غير قابلة للضبط 
delete empCount;  // false 

// حذف إحدى خاصيات الكائن  
delete EmployeeDetails.name; // true 

// حذف خاصية غير موجودة
delete EmployeeDetails.salary; // true

لا يملك المعامل delete أي تأثير على الخاصيات الساكنة للكائنات المُضمَّنة في لغة JavaScript مثل كائن Math؛ لاحظ أنَّ بإمكاننا حذف الكائن EmployeeDetails لأنه إحدى خاصيات الكائن العام وقد عُرِّف دون استخدام الكلمة المحجوزة var، أي أنَّه خاصيةٌ قابلةٌ للضبط:

delete Math.PI; // false 
delete EmployeeDetails; // true

لن يؤثر المعامل delete على المتغيرات المحلية المُنشَأة داخل إحدى الدوال:

function f() {
  var z = 44;
  delete z; // false
}

المعامل delete وسلسلة prototype

سنحذف في المثال الآتي خاصيةً تابعةً لأحد الكائنات بينما ستبقى خاصيةٌ لها نفس الاسم متاحةً في سلسلة prototype:

function Foo() {
  this.bar = 10;
}

Foo.prototype.bar = 42;

var foo = new Foo();

// حُذِفَت الخاصية التابعة للكائن مباشرةً
delete foo.bar; // true

// سنستطيع الوصول إلى الخاصية الموجودة في كائن prototype
console.log(foo.bar);

// سنحذف الخاصية الموجودة في كائن prototype
delete Foo.prototype.bar; 

// لم تعد هنالك خاصيةٌ بهذا الاسم؛ سواءً كانت تابعةً للكائن مباشرةً، أو موروثةً
console.log(foo.bar); // undefined

حذف عناصر المصفوفات

عندما تحذف أحد عناصر المصفوفة، فلن يتأثر طول المصفوفة، حتى لو كان العنصر الذي حذفته هو آخر عنصر في المصفوفة.

عند حذف عنصر من عناصر المصفوفة عبر المعامل delete فلن يبقى هذا العنصر موجودًا في المصفوفة، لاحظ أثر حذف العنصر ‎tress[3]‎‎ في المثال الآتي باستخدام المعامل delete:

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];
if (3 in trees) {
    // لن تُنفَّذ الشيفرات هنا
}

إذا أردت أن يكون أحد عناصر المصفوفة موجودًا لكن قيمته غير مُعرَّفة، فاستخدم القيمة undefined بدلًا من المعامل delete، ففي المثال الآتي أسندنا القيمة undefined إلى العنصر ‎tress[3]‎‎:

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees[3] = undefined;
if (3 in trees) {
    // ستُنفَّذ الشيفرات الموجودة هنا
}

دعم المتصفحات

الميزة Chrome Firefox Internet Explorer Opera Safari
الدعم الأساسي نعم نعم نعم نعم نعم

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