الطريقة الصحيحة لإعادة ضبط أو مسح كائن JavaScript؟
-
09-09-2019 - |
سؤال
لدي فئة JavaScript التي تحتوي على عدد قليل من الوظائف وكائنات الأعضاء:
function MyUtils()
{
// Member Variables (Constructor)
var x = getComplexData();
var y = doSomeInitialization();
// Objects
this.ParamHash = function()
{
// Member variables
this.length = 0;
this.items = new Array();
// Constructor
for (var i = 0; i < arguments.length; i += 2)
{
// Fill the items array.
this.items[arguments[i]] = arguments[i+1];
this.length++;
}
}
// Functions
this.doSomething = function()
{
// Do something.
// Uses the items in the ParamHash object.
for (var i in this.ParamHash.items)
{
// Really do something!
}
// Clear the ParamHash object -- How??
}
}
تم استدعاء هذا بالطريقة التالية:
// First call - works fine.
var utils = new MyUtils();
utils.paramHash = new utils.ParamHash("a", 1, "b", 2);
utils.doSomething();
// Don't want to re-initialize.
// utils = new MyUtils();
// Consequent call - crashes ["Object doesn't support this action."].
utils.paramHash = new utils.ParamHash("c", 3);
utils.doSomething();
تنشأ المشكلة من القيود التي أريد إعادة استخدامها utils
كائن في جميع أنحاء التعليمات البرمجية دون الحاجة إلى إعادة تهيئة ذلك. أيضا، أريد إعادة إنشاء كائن Paramhash من نقطة الصفر في كل مرة أسميها. ومع ذلك، فإن المكالمات الناتجة إلى منشئ Paramhash رمي خطأ "كائن لا يدعم هذا الإجراء." في هذه المرحلة، أستطيع أن أرى أن كائن Utils.Paramhash لا يزال يحتوي على القيم القديمة ("A"، "B").
لقد جربت طرق مختلفة لمسح كائن Paramhash مثل إعداد العناصر والطول إلى NULL، بعناصر ظهرت من الصفيف. لا شيء يبدو أنه يعمل حتى استخدم الطريقة التالية (في doSomething()
وظيفة):
this.paramHash.items = new Array();
this.paramHash.length = 0;
يبدو هذا خطأ لأن ماذا لو كان لدي الكثير من المتغيرات الأعضاء ... هل يجب علي إعادة تعيين كل منهم بشكل فردي؟ لذلك، السؤال هو: ما هي أفضل طريقة لإعادة تعيين ParamHash
الاعتراض على الحالة الأولية؟ أنا متأكد من أنني آمل أن تكون هناك طريقة نظافة / أكثر مباشرة. شيء مثل :
// Doesn't work! :-(
this.paramHash = new function() {};
تحرير: أبحث عن حل متصفح - واحد يعمل على الأقل في IE6 + و FF 2+.
المحلول: بفضل كريستوف، كنت قادرا على القيام بذلك عن طريق إنشاء متغير منفصل / ممتلكات داخل MyUtils
الذي يحمل فقط مثيل ParamHash
وظيفة.
function MyUtils()
{
// Same ol' stuff.
var myParamHash;
}
// First call - works fine.
var utils = new MyUtils();
utils.myParamHash = new utils.ParamHash("a", 1, "b", 2);
utils.doSomething();
// Consequent call - works fine now.
utils.myParamHash = new utils.ParamHash("c", 3);
utils.doSomething();
المحلول
هذه
utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);
الكتابة فوق العقار الذي يحمل ParamHash()
وظيفة المنشئ مع كائن مثيل. يمكنك الحصول على المنشئ مرة أخرى عبر
utils.ParamHash.constructor
ولكن الطريقة الأنظف لن تكون الكتابة فوقها في المقام الأول واستخدام خاصية منفصلة لعقد المثيل.
لا أعرف المشكلة الدقيقة تحاول Cerebrus حلها، لذلك قد تكون هناك أسباب صالحة لما يفعله. ولكن في رأيي، حل محله معقد للغاية. سأفعل شيئا مثل هذا:
function MyUtils() {
this.x = getComplexData();
this.y = doSomeInitialization();
this.params = {};
}
MyUtils.prototype.doSomething = function() {
for(var prop in this.params) {
if(this.params.hasOwnProperty(prop)) {
// do stuff
}
}
};
var utils = new MyUtils;
utils.params = { a : 1, b : 2 };
utils.doSomething();
الاختيار ل hasOwnProperty()
غير ضروري إذا كنت تستطيع أن تتأكد من عدم وجود أحد Object.prototype
.
بعض التعليقات الإضافية:
- في جافا سكريبت، عادة ما يتم رسملة أسماء وظائف المنشئ فقط
items
لا ينبغي أن يكون صفيف، ولكن كائن عادي، أيthis.items = {};
نصائح أخرى
عندما فعلت هذا
utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);
قمت باستبدال وظيفة منشئ Paramhash مع مثيل كائن. لاحق new ParamHash()
فشل لأن Utils.Paramhash لم يعد وظيفة منشئ.
جرب هذا:
var utils = new MyUtils();
utils.paramHashInstance = new utils.ParamHash("a", 1, "b", 2);
utils.DoSomething();
هل حاولت حذف الكلمة الرئيسية الجديدة؟
utils.ParamHash = utils.ParamHash("c", 3);