[Javascript] جافا سكريبت متغير عدد من الحجج للعمل


Answers

خيار آخر هو تمرير وسيطاتك في كائن سياق.

function load(context)
{
    // do whatever with context.name, context.address, etc
}

واستخدامها هكذا

load({name:'Ken',address:'secret',unused:true})

هذا له ميزة أنه يمكنك إضافة العديد من الحجج المسماة كما تريد ، ويمكن أن تستخدم الدالة (أو لا) كما تراه مناسبًا.

Question

هل هناك طريقة للسماح بظهور "غير محدود" لوظيفة في JavaScript؟

مثال:

load(var1, var2, var3, var4, var5, etc...)
load(var1)



استخدم كائن arguments داخل الوظيفة للوصول إلى جميع الوسائط التي تم تمريرها.




في حين أظهرroufamatic استخدام الكلمة الرئيسية للحجج وعرضتKen مثالا رائعا عن كائن للاستخدام أشعر أنني لم أتعامل مع ما يحدث بالفعل في هذه الحالة ويمكن أن نخلط بين القراء المستقبليين أو نزرع ممارسة سيئة لا تنص بوضوح على وظيفة / method يهدف إلى أخذ كمية متغيرة من الوسيطات / المعلمات.

function varyArg () {
    return arguments[0] + arguments[1];
}

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

دعونا نذكر بوضوح أن نفس الوظيفة لها معلمات متغيرة:

function varyArg (var_args) {
    return arguments[0] + arguments[1];
}

معلمة الكائن VS var_args

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

SIDENOTE: ترجع الكلمة المفتاحية إلى كائن باستخدام الأرقام كمفتاح. الميراث نموذجي هو أيضا الكائن الكائن. انظر نهاية الإجابة لاستخدام الصفيف المناسب في JS

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

function varyArg (args_obj) {
    return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});

أي واحد تختار؟

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

استخدام الحجج

function sumOfAll (var_args) {
    return arguments.reduce(function(a, b) {
        return a + b;
    }, 0);
}
sumOfAll(1,2,3); // returns 6

استخدام الكائن

function myObjArgs(args_obj) {
    // MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
    if (typeof args_obj !== "object") {
        return "Arguments passed must be in object form!";
    }

    return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old

الوصول إلى مصفوفة بدلاً من كائن ("... ... args") المعلمة الباقية

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

Array.prototype.map.call(arguments, function (val, idx, arr) {});

لتجنب هذا الاستخدام المعلمة بقية:

function varyArgArr (...var_args) {
    return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5



على الرغم من أنني أوافق بشكل عام على أن نهج الحجج المسمى مفيد ومرن (إلا إذا كنت مهتمًا بالترتيب ، وفي هذه الحالة تكون الحجج أسهل) ، فإن لدي مخاوف بشأن تكلفة نهج mbeasley (باستخدام الافتراضات والتوسعات). هذا هو مقدار التكلفة القصوى التي يجب اتخاذها لسحب القيم الافتراضية. أولاً ، يتم تعريف الإعدادات الافتراضية داخل الدالة ، بحيث يتم إعادة ملؤها في كل مكالمة. ثانيًا ، يمكنك بسهولة قراءة القيم المسماة وتعيين الإعدادات الافتراضية في نفس الوقت باستخدام || ليست هناك حاجة لإنشاء ودمج كائن جديد آخر للحصول على هذه المعلومات.

function load(context) {
   var parameter1 = context.parameter1 || defaultValue1,
       parameter2 = context.parameter2 || defaultValue2;

   // do stuff
}

هذا هو نفس المقدار من التعليمات البرمجية (ربما أكثر قليلاً) ، ولكن يجب أن يكون جزءًا من تكلفة وقت التشغيل.




أتفق مع إجابة كين باعتبارها الأكثر ديناميكية وأحب أن أتقدم بها خطوة أخرى. إذا كانت هذه هي الدالة التي تستدعيها عدة مرات باستخدام وسيطات مختلفة - فأنا أستخدم تصميم Ken ولكن أضف القيم الافتراضية:

function load(context) {

    var defaults = {
        parameter1: defaultValue1,
        parameter2: defaultValue2,
        ...
    };

    var context = extend(defaults, context);

    // do stuff
}

بهذه الطريقة ، إذا كان لديك العديد من المعلمات ولكنك لا تحتاج بالضرورة إلى تعيينها مع كل مكالمة إلى الوظيفة ، فيمكنك ببساطة تحديد غير الافتراضيات. بالنسبة لطريقة التمديد ، يمكنك استخدام طريقة تمديد jQuery ( $.extend() ) ، أو إنشاء الحرف الخاص بك أو استخدام ما يلي:

function extend() {
    for (var i = 1; i < arguments.length; i++)
        for (var key in arguments[i])
            if (arguments[i].hasOwnProperty(key))
                arguments[0][key] = arguments[i][key];
    return arguments[0];
}

سيؤدي ذلك إلى دمج كائن السياق مع الإعدادات الافتراضية وملء أي قيم غير محددة في الكائن باستخدام الإعدادات الافتراضية.




Links