سؤال

لدي فئة 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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top