delete - properties javascript




كيف أقوم بإزالة خاصية من كائن JavaScript؟ (20)

قل أن أقوم بإنشاء كائن على النحو التالي:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

ما هي أفضل طريقة لإزالة الخاصية regex حتى ينتهي بـ myObject الجديد كما يلي؟

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};

2 المنتشرة (ES6)

لمن يحتاجها ...

لإكمالKoen الإجابة في هذا الموضوع ، إذا كنت تريد إزالة متغير ديناميكي باستخدام صيغة الانتشار ، فيمكنك القيام بذلك كما يلي:

const key = 'a';

const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };

console.log(rest); // { b: 2, c: 3 }

* fooسيكون متغيرًا جديدًا بقيمة a(وهو 1).


استكمال :
هناك عدد قليل من الطرق الشائعة لإزالة خاصية من كائن.
كل واحد لديه إيجابيات وسلبيات خاصة به ( تحقق من مقارنة الأداء هذه ):

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
قراءته وقصره ، ومع ذلك قد لا يكون الخيار الأفضل إذا كنت تعمل على عدد كبير من الكائنات حيث لم يتم تحسين أدائه.

delete obj[key];


Reassignment
أكثر من 2X أسرع منdelete، ومع ذلكلايتمحذفالخاصيةويمكن تكرارها.

obj[key] = null;
obj[key] = false;
obj[key] = undefined;


Spread Operator يتيح لنا
هذاES6المشغل إعادة كائن جديد تمامًا ، باستثناء أي خصائص ، دون تحور الكائن الموجود. الجانب السلبي هو أنه يحتوي على أداء أسوأ من أعلاه وليس مقترحا لاستخدامه عندما تحتاج إلى إزالة العديد من الخصائص في كل مرة.

{ [key]: val, ...rest } = obj;

Object.assign () & Object.keys () & Array.map ()

const obj = {
    "Filters":[
        {
            "FilterType":"between",
            "Field":"BasicInformationRow.A0",
            "MaxValue":"2017-10-01",
            "MinValue":"2017-09-01",
            "Value":"Filters value"
        }
    ]
};

let new_obj1 = Object.assign({}, obj.Filters[0]);
let new_obj2 = Object.assign({}, obj.Filters[0]);

/*

// old version

let shaped_obj1 = Object.keys(new_obj1).map(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
        }
        return new_obj1;
    }
)[0];


let shaped_obj2 = Object.keys(new_obj2).map(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
        return new_obj2;
    }
)[0];


*/


// new version!

let shaped_obj1 = Object.keys(new_obj1).forEach(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
            default:
                break;
        }
    }
);

let shaped_obj2 = Object.keys(new_obj2).forEach(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
    }
);


delete مشغل بطيئة بشكل غير متوقع!

انظر إلى benchmark .

الحذف هو الطريقة الوحيدة الحقيقية لإزالة خصائص الكائن دون أي بقايا ، لكنه يعمل ~ 100 مرة أبطأ ، مقارنة بـ "البديل" ، إعداد object[key] = undefined .

هذا البديل ليس الجواب الصحيح لهذا السؤال! ولكن ، إذا استخدمته بعناية ، يمكنك تسريع بعض الخوارزميات بشكل كبير. إذا كنت تستخدم delete في حلقات ولديك مشكلات في الأداء ، فاقرأ الشرح المطول.

متى يجب استخدام delete وعند تعيين القيمة على undefined ؟

قد يتم اعتبار الكائن كمجموعة من أزواج القيم الرئيسية. ما أسميه "قيمة" هو بدائي أو إشارة إلى كائن آخر ، متصل بهذا "المفتاح".

استخدم delete ، عندما تمرر كائن النتيجة إلى الرمز الذي لا تتحكم فيه (أو عندما تكون غير متأكد من فريقك أو نفسك).

يحذف المفتاح من hashmap .

 var obj = {
     field: 1     
 };
 delete obj.field;

استخدم الإعداد إلى undefined ، عندما تهتم بالأداء. يمكن أن يعطي دفعة قوية لشفائك.

يبقى المفتاح على مكانه في hashmap ، يتم استبدال القيمة فقط مع undefined . نفهم ، أن ل for..in حلقة لا تزال تتكرر على هذا المفتاح.

 var obj = {
     field: 1     
 };
 obj.field = undefined;

باستخدام هذه الطريقة ، لن تعمل كافة الطرق لتحديد وجود خاصية كما هو متوقع.

ومع ذلك ، فإن هذا الرمز:

object.field === undefined

سوف تتصرف على قدم المساواة لكلا الطريقتين.

اختبارات

لتلخيص ، الاختلافات كلها عن طرق لتحديد وجود خاصية ، وحول ل for..in حلقة.

 console.log('* -> "Takes prototype inheritance into consideration, that means it lookups all over prototype chain too."');

 console.log(obj.field === undefined, 'obj.field === undefined', 'You get "undefined" value when querying for "field" in object-hashmap. *');

 console.log(obj["field"] === undefined, 'obj["field"] === undefined', 'Just another way to query (equivalent). *');

 console.log(typeof obj.field === "undefined", 'typeof obj.field === "undefined"', 'Get the value attached to "field" key, and check it\'s type is "undefined". *');

 console.log("field" in obj, '"field" in obj', 'This statement returns true if "field" key exists in the hashmap. False otherwise. *');

 console.log(obj.hasOwnProperty("field"), 'obj.hasOwnProperty("field")', 'This statement returns true if \'field\' key exists in the hashmap. The ONLY way NOT to lookup for property in the prototype chain!');
 //Object.keys().indexOf() is an overkill that runs much slower :)

 var counter = 0,
     key;
 for (key in obj) {
     counter++;
 }
 console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *');

حذار من تسرب الذاكرة!

في حين أن استخدام obj[prop] = undefined هو أسرع من فعل delete obj[prop] ، فإن هناك اعتبارًا مهمًا آخر هو أن obj[prop] = undefined قد لا يكون مناسبًا دائمًا. delete obj[prop] يزيل prop من obj ويمحوها من الذاكرة في حين obj[prop] = undefined يضبط قيمة prop ببساطة إلى undefined الذي يترك prop في الذاكرة. لذلك ، في الحالات التي يوجد فيها العديد من المفاتيح التي يتم إنشاؤها وحذفها ، يمكن أن يؤدي استخدام obj[prop] = undefined إجبار الذاكرة على التوفيق (مما يؤدي إلى تجميد الصفحة) واحتمال حدوث خطأ خارج الذاكرة. افحص التعليمة البرمجية التالية.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /*************************************************/
            /****/ nodeRecords[i][lastTime] = undefined; /****/
            /*************************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

في التعليمة البرمجية المذكورة أعلاه ، ما nodeRecords[i][lastTime] = undefined; سوى إجراء nodeRecords[i][lastTime] = undefined; سوف يسبب تسرب ذاكرة هائلة بسبب كل إطار للرسوم المتحركة. كل إطار ، كل عناصر الـ 65536 DOM ستشغل 65536 فتحات فردية أخرى ، لكن الفتحات السابقة 65536 سيتم ضبطها فقط إلى غير محدد مما يتركها معلقة في الذاكرة. المضي قدما ، في محاولة لتشغيل التعليمات البرمجية أعلاه في وحدة التحكم ونرى بنفسك. بعد فرض خطأ خارج الذاكرة ، حاول تشغيله مرة أخرى باستثناء الإصدار التالي من التعليمات البرمجية التي تستخدم عامل delete بدلاً من ذلك.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /********************************************/
            /****/ delete nodeRecords[i][lastTime]; /****/
            /********************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

كما هو موضح في مقتطف الشفرة الموضح أعلاه ، توجد بعض حالات الاستخدام المناسبة النادرة لمشغل delete . ومع ذلك ، لا تقلق بشأن هذه المشكلة أكثر من اللازم. سيصبح هذا فقط مشكلة في الكائنات طويلة العمر التي تحصل على مفاتيح جديدة تضيفها باستمرار. في أي حالة أخرى (وهو ما يقرب من كل حالة في برمجة العالم الحقيقي) ، فمن الأنسب استخدام obj[prop] = undefined . الغرض الرئيسي من هذا القسم هو فقط لفت انتباهك إلى هذا الأمر ، بحيث أنه في فرصة نادرة أن تصبح هذه مشكلة في شفرتك ، عندها يمكنك فهم المشكلة بسهولة أكبر وبالتالي لا يجب أن تضيع ساعات تشريح شفرتك لتحديد مكانها. وفهم هذه المشكلة.

لا دائما تعيين undefined

أحد جوانب جافا سكريبت التي يجب أخذها بعين الاعتبار هو تعدد الأشكال. تعدد الأشكال هو عند تعيين نفس الأنواع المختلفة المتغيرة / فتحة في كائن كما هو موضح أدناه.

var foo = "str";
foo = 100;          // variable foo is now labeled polymorphic by the browser
var bar = ["Some", "example"];
bar[2] = "text";    // bar is a monomorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = undefined; // bar is now a polymorphic array

ومع ذلك ، هناك مشكلتين رئيسيتين غير قابلتين للإصلاح مع صفائف متعددة الأشكال:

  1. فهي بطيئة والذاكرة غير فعالة. عند الوصول إلى فهرس معين ، بدلاً من مجرد الحصول على النوع العام للمصفوفة ، يجب أن يحصل المستعرض بدلاً من ذلك على النوع على أساس كل فهرس ، حيث يخزن كل فهرس البيانات الأولية الإضافية من نوعها.
  2. مرة واحدة متعددة الأشكال ، دائما متعددة الأشكال. عندما يصنع صفيف متعدد الأشكال ، لا يمكن التراجع عن تعدد الأشكال في متصفحات Webkit. لذا ، حتى إذا قمت باستعادة مصفوفة متعددة الأشكال إلى أن تكون غير متعددة الأشكال ، فسيظل تخزينها من قبل المستعرض كمجموعة متعددة الأشكال.

قد يشبه المرء تعدد الأشكال إلى إدمان المخدرات. للوهلة الأولى ، يبدو مربحا بذهول: رمز رقيق جميل. ثم ، يقدم المبرمج صفيفهم لعقار تعدد الأشكال. على الفور ، تصبح المجموعة متعددة الأشكال أقل كفاءة ، ولا يمكن أن تصبح فعالة كما كانت من قبل حيث يتم تخديرها. لربط مثل هذا الظرف بالحياة الحقيقية ، قد لا يكون شخص ما على الكوكايين قادراً على تشغيل مقبض باب بسيط ، ناهيك عن القدرة على حساب أرقام PI. وبالمثل ، فإن صفيفًا من دواء تعدد الأشكال لا يمكن أبدًا أن يكون بنفس كفاءة المصفوفة أحادية الشكل.

ولكن ، كيف يرتبط قياس رحلة الدواء بعملية delete ؟ يكمن الحل في السطر الأخير من التعليمة البرمجية في المقتطف أعلاه. لذا دعنا نعيد فحصها ، هذه المرة مع تطور.

var bar = ["Some", "example"];
bar[2] = "text";    // bar is not a polymorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = "";        // bar is still a monomorphic array
bar[1] = undefined; // bar is now a polymorphic array

رصد. bar[1] = "" إجبار تعدد الأشكال في حين أن bar[1] = undefined . لذلك ، يجب دائمًا ، عند الإمكان ، استخدام النوع المطابق لأجسامها بحيث لا تسبب تعدد الأشكال بطريق الخطأ. قد يستخدم أحد هؤلاء الأشخاص القائمة التالية كمرجع عام لحملهم على الذهاب. ومع ذلك ، يرجى عدم استخدام الأفكار التالية بوضوح. بدلاً من ذلك ، استخدم كل ما يعمل جيدًا للشفرة.

  • عند استخدام صفيف / متغير مكتوب بلغة بدائية ، استخدم إما false أو undefined كقيمة فارغة. في حين أن تجنب تعدد الأشكال غير الضروري أمر جيد ، فإن إعادة كتابة جميع التعليمات البرمجية الخاصة بك لمنعها صراحةً من المحتمل أن يؤدي في الواقع إلى انخفاض في الأداء. استخدام الحكم المشترك!
  • عند استخدام صفيف / متغير مطبوع على الرقم البدائي ، استخدم 0 كقيمة فارغة. لاحظ أنه داخليًا ، هناك نوعان من الأرقام: الأعداد الصحيحة السريعة (2147483647 إلى -2147483648 شاملة) والنقاط العائمة المزدوجة البطيئة (أي شيء آخر غير ذلك بما في ذلك NaN و Infinity ). عندما يتم تخفيض عدد صحيح إلى مزدوج ، لا يمكن ترقيته مرة أخرى إلى عدد صحيح.
  • عند استخدام صفيف / متغير كتبته السلسلة الأولية ، استخدم "" كقيمة فارغة.
  • عند استخدام الرمز ، انتظر ، لماذا تستخدم الرمز؟!؟! الرموز هي juju سيئة للأداء. كل شيء مبرمج لاستخدام الرموز يمكن إعادة برمجته لعدم استخدام الرموز ، مما يؤدي إلى رمز أسرع بدون رموز. الرموز هي في الواقع مجرد سوبر ميتا سكر غير فعال.
  • عند استخدام أي شيء آخر ، استخدم القيمة null .

ومع ذلك ، يجب أن تضع في اعتبارها! لا تبدأ فجأة في القيام بذلك مع كل التعليمات البرمجية الموجودة لديك من قبل حيث أنه من المرجح كسر مثل هذه التعليمة البرمجية الموجودة و / أو إدخال أخطاء غريبة. بدلاً من ذلك ، يجب تنفيذ مثل هذه الممارسة الفعالة من البداية ، وعند تحويل الشفرة الموجودة مسبقًا ، يُنصح بأن تقوم بالتحقق من كل الأسطر المتعلقة بثلاثة أضعاف وثلاثة أضعاف هذه الخطوط ، حيث أن محاولة ترقية الرمز القديم إلى هذه الممارسة الجديدة يمكن أن تكون محفوفة بالمخاطر كما هو مجزي.


السؤال القديم ، والإجابة الحديثة. باستخدام كائن destructuring ، ميزة ECMAScript 6 ، انها بسيطة مثل:

const { a, ...rest } = { a: 1, b: 2, c: 3 };

أو مع عينة الأسئلة:

const myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
const { regex, ...newObject } = myObject;
console.log(newObject);

يمكنك رؤيته في العمل في محرر بابل للتجربة.

تصحيح:

لإعادة تعيين نفس المتغير ، استخدم let :

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);

مثله:

delete myObject.regex;
// or,
delete myObject['regex'];
// or,
var prop = "regex";
delete myObject[prop];

عرض

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};
delete myObject.regex;

console.log(myObject);

لأي شخص مهتم في قراءة المزيد حول هذا الموضوع ، قام مستخدم kangax بكتابة kangax في العمق بشكل لا يصدق حول عبارة delete في مدونته ، فهم الحذف . ينصح بشدة.


يمكن تفسير المصطلح الذي استخدمته في عنوان السؤال الخاص بك ، Remove a property from a JavaScript object ، بطرق مختلفة. واحد هو إزالته لكامل الذاكرة وقائمة مفاتيح الكائن أو الآخر هو فقط لإزالته من الكائن الخاص بك. كما ذكر في بعض الإجابات الأخرى ، فإن الكلمة الرئيسية delete هي الجزء الرئيسي. لنفترض أن لديك كائنًا مثل:

myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

اذا فعلت:

console.log(Object.keys(myJSONObject));

ستكون النتيجة:

["ircEvent", "method", "regex"]

يمكنك حذف هذا المفتاح المحدد من مفاتيح الكائن مثل:

delete myJSONObject["regex"];

ثم سيكون مفتاح الكائنات الخاص بك باستخدام Object.keys(myJSONObject) :

["ircEvent", "method"]

لكن الهدف هو إذا كنت تهتم بالذاكرة وترغب في إزالة الكائن من الذاكرة ، فمن المستحسن تعيينه إلى الصفر قبل حذف المفتاح:

myJSONObject["regex"] = null;
delete myJSONObject["regex"];

النقطة المهمة الأخرى هنا هي أن تكون حذرا حول مراجعك الأخرى لنفس الشيء. على سبيل المثال ، إذا قمت بإنشاء متغير مثل:

var regex = myJSONObject["regex"];

أو إضافته كمؤشر جديد إلى كائن آخر مثل:

var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];

ثم حتى إذا قمت بإزالته من myJSONObject الكائن الخاص بك ، فلن يتم حذف هذا الكائن المحدد من الذاكرة ، حيث أن متغير regex و myOtherObject["regex"] لا يزال لديهم قيمهم. ثم كيف يمكننا إزالة الكائن من الذاكرة بالتأكيد؟

ستكون الإجابة هي حذف جميع المراجع الموجودة في شفرتك ، والإشارة إلى ذلك الكائن ذاته وعدم استخدام عبارات var لإنشاء مراجع جديدة لهذا الكائن . هذه النقطة الأخيرة بخصوص العبارات var ، هي واحدة من أهم القضايا التي نواجهها عادة ، لأن استخدام العبارات var سيمنع الكائن الذي تم إنشاؤه من إزالته.

مما يعني أنه في هذه الحالة لن تتمكن من إزالة هذا الكائن لأنك قمت بإنشاء متغير regex عبر عبارة var ، وإذا قمت بذلك:

delete regex; //False

ستكون النتيجة false ، مما يعني أن بيان الحذف الخاص بك لم يتم تنفيذه كما هو متوقع. ولكن إذا لم تكن قد قمت بإنشاء هذا المتغير من قبل ، وكان لديك فقط myOtherObject["regex"] كمرجع آخر موجود لديك ، فقد كان بإمكانك فعل ذلك فقط عن طريق إزالته مثل:

myOtherObject["regex"] = null;
delete myOtherObject["regex"];

وبعبارة أخرى ، يتم قتل كائن جافا سكريبت بمجرد عدم وجود مرجع يسار في التعليمة البرمجية الخاصة بك إلى هذا الكائن.

تحديث: شكرًا علىAgentME:

لا يؤدي تعيين خاصية إلى null قبل حذفها إلى إنجاز أي شيء (ما لم يتم إغلاق الكائن بواسطة Object.seal ويفشل الحذف. لا يحدث ذلك عادة إلا إذا حاولت ذلك تحديدًا).

للحصول على مزيد من المعلومات حول Object.seal: Object.seal()


إذا كنت ترغب في حذف خاصية متداخلة بعمق في الكائن ، فيمكنك استخدام الدالة العودية التالية مع المسار إلى الخاصية كوسيطة ثانية:

var deepObjectRemove = function(obj, path_to_key){
    if(path_to_key.length === 1){
        delete obj[path_to_key[0]];
        return true;
    }else{
        if(obj[path_to_key[0]])
            return deepObjectRemove(obj[path_to_key[0]], path_to_key.slice(1));
        else
            return false;
    }
};

مثال:

var a = {
    level1:{
        level2:{
            level3: {
                level4: "yolo"
            }
        }
    }
};

deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);

//Prints {level1: {level2: {}}}

باستخدام ES6:

(مشغل Destructuring + Spread)

    const myObject = {
      regex: "^http://.*",
      b: 2,
      c: 3
    };
    const { regex, ...noRegex } = myObject;
    console.log(noRegex); // => { b: 2, c: 3 }

بسيط جدا:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

delete myObject.regex;

جرب هذا

delete myObject['key'];

مرحبا يمكنك أن تجرب هذا النوع البسيط

var obj = [];

obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};

delete(obj.key1);

هذه المشاركة قديمة جدًا وأجدها مفيدة جدًا لذا قررت مشاركة وظيفة غير محددة كتبت في حالة رؤية شخص آخر لهذه المشاركة والتفكير في سبب أنها ليست بهذه البساطة كما هو الحال في وظيفة PHP.

سبب كتابة هذه unsetالوظيفة الجديدة هو الاحتفاظ بفهرس جميع المتغيرات الأخرى في هذا hash_map. انظر إلى المثال التالي ، وشاهد كيف أن مؤشر "test2" لم يتغير بعد إزالة قيمة من hash_map.

function unset(unsetKey, unsetArr, resort){
  var tempArr = unsetArr;
  var unsetArr = {};
  delete tempArr[unsetKey];
  if(resort){
    j = -1;
  }
  for(i in tempArr){
    if(typeof(tempArr[i]) !== 'undefined'){
      if(resort){
        j++;
      }else{
        j = i;
      }
      unsetArr[j] = tempArr[i];
    }
  }
  return unsetArr;
}

var unsetArr = ['test','deletedString','test2'];

console.log(unset('1',unsetArr,true)); // output Object {0: "test", 1: "test2"}
console.log(unset('1',unsetArr,false)); // output Object {0: "test", 2: "test2"}

var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
    
delete myObject.regex;

console.log ( myObject.regex); // logs: undefined

هذا يعمل في فايرفوكس وإنترنت إكسبلورر ، وأعتقد أنه يعمل في جميع الآخرين.


const myObject = {
        "ircEvent": "PRIVMSG",
        "method": "newURI",
        "regex": "^http://.*"
    };

const { regex, ...other } = myObject;

console.log(myObject)
console.log(regex)
console.log(other)


باستخدام ramda#dissoc ستحصل على كائن جديد بدون السمة regex:

const newObject = R.dissoc('regex', myObject);
// newObject !== myObject

يمكنك أيضا استخدام وظائف أخرى لتحقيق نفس التأثير - حذف ، اختيار ، ...


تأكيد دان أن "الحذف" بطيء للغاية وأن المؤشر الذي نشره كان موضع شك. لذلك أجريت الاختبار بنفسي في Chrome 59. يبدو أن "الحذف" أبطأ بنحو 30 مرة:

var iterationsTotal = 10000000;  // 10 million
var o;
var t1 = Date.now(),t2;
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   delete o.a; delete o.b; delete o.c; delete o.d; delete o.e;
}
console.log ((t2=Date.now())-t1);  // 6135
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   o.a = o.b = o.c = o.d = o.e = undefined;
}
console.log (Date.now()-t2);  // 205

لاحظ أنني قمت بتنفيذ أكثر من عملية "حذف" واحدة في دورة حلقة واحدة لتقليل التأثير الناتج عن العمليات الأخرى.


جرب الطريقة التالية. قم بتعيين Objectقيمة الخاصية إلى undefined. ثم stringifyالكائن و parse.

 var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));

console.log(myObject);


حل آخر ، وذلك باستخدام Array#reduce.

var myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

myObject = Object.keys(myObject).reduce(function(obj, key) {
  if (key != "regex") {           //key you want to remove
    obj[key] = myObject[key];
  }
  return obj;
}, {});

console.log(myObject);

ومع ذلك ، فإنه سيتم تحوير الكائن الأصلي. إذا كنت تريد إنشاء كائن جديد بدون المفتاح المحدد ، فكل ما عليك فعله هو تعيين وظيفة تقليل إلى متغير جديد ، على سبيل المثال:

(ES6)

const myObject = {
  ircEvent: 'PRIVMSG',
  method: 'newURI',
  regex: '^http://.*',
};

const myNewObject = Object.keys(myObject).reduce((obj, key) => {
  key !== 'regex' ? obj[key] = myObject[key] : null;
  return obj;
}, {});

console.log(myNewObject);



يعد استخدام طريقة الحذف أفضل طريقة للقيام بذلك ، وفقًا لوصف MDN ، يقوم عامل الحذف بإزالة خاصية من كائن. لذا يمكنك ببساطة أن تكتب:

delete myObject.regex;
// OR
delete myObject['regex'];

يقوم عامل حذف بإزالة خاصية معينة من كائن. عند الحذف الناجح ، فإنه سيعود صحيح ، وإلا سيتم إرجاع خطأ. ومع ذلك ، من المهم مراعاة السيناريوهات التالية:

  • إذا كانت الخاصية التي تحاول حذفها غير موجودة ، فلن يكون للحذف أي تأثير وسيعود إلى true

  • إذا كانت الخاصية التي لها نفس الاسم موجودة على سلسلة النموذج الأولي للكائن ، فعندها بعد الحذف ، سيستخدم الكائن الخاصية من سلسلة النموذج الأولي (وبعبارة أخرى ، يكون للحذف تأثير فقط على الخصائص الخاصة به).

  • لا يمكن حذف أي خاصية تم التصريح عنها بالقيمة var من النطاق العالمي أو من نطاق الدالة.

  • على هذا النحو ، لا يمكن حذف حذف أي وظائف في النطاق العالمي (سواء كان ذلك جزءًا من تعريف دالة أو دالة (تعبير).


  • يمكن حذف الوظائف التي تعد جزءًا من كائن ما (بخلاف النطاق العالمي) بحذف.

  • لا يمكن حذف أي خاصية يتم الإعلان عنها باستخدام السماح أو const من النطاق الذي تم تعريفها فيه. لا يمكن إزالة الخصائص غير القابلة للتكوين. يتضمن هذا خصائص كائنات مضمنة مثل Math و Array و Object وخصائص تم إنشاؤها على أنها غير قابلة للتكوين باستخدام أساليب مثل Object.defineProperty ().

المقتطف التالي يعطي مثالًا بسيطًا آخر:

var Employee = {
      age: 28,
      name: 'abc',
      designation: 'developer'
    }
    
    console.log(delete Employee.name);   // returns true
    console.log(delete Employee.age);    // returns true
    
    // When trying to delete a property that does 
    // not exist, true is returned 
    console.log(delete Employee.salary); // returns true

لمزيد من المعلومات حول المزيد من الأمثلة ورؤيتها ، تفضل بزيارة الرابط أدناه:

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…





object-properties