how أفضل طريقة لتحديد ما إذا لم يتم إرسال وسيطة إلى وظيفة JavaScript




how to call javascript function in html (9)

لقد رأيت الآن طريقتين لتحديد ما إذا تم تمرير وسيطة إلى وظيفة JavaScript. أتساءل إذا كانت إحدى الطرق أفضل من الأخرى أو إذا كان أحدها سيئ الاستخدام؟

 function Test(argument1, argument2) {
      if (Test.arguments.length == 1) argument2 = 'blah';

      alert(argument2);
 }

 Test('test');

أو

 function Test(argument1, argument2) {
      argument2 = argument2 || 'blah';

      alert(argument2);
 }

 Test('test');

بقدر ما أستطيع أن أقول ، كلاهما ينتجان نفس الشيء ، لكني استعملت الشيء الأول فقط من قبل في الإنتاج.

خيار آخر كما ذكر Tom :

function Test(argument1, argument2) {
    if(argument2 === null) {
        argument2 = 'blah';
    }

    alert(argument2);
}

وفقًا لتعليق خوان ، سيكون من الأفضل تغيير اقتراح توم إلى:

function Test(argument1, argument2) {
    if(argument2 === undefined) {
        argument2 = 'blah';
    }

    alert(argument2);
}

أنا آسف ، ما زلت لا أستطيع التعليق ، لذا للإجابة على جواب توم ... في javascript (undefined! = null) == false في الواقع لن تعمل هذه الدالة مع "null" ، يجب عليك استخدام "غير معرفة"



في ES6 (ES2015) ، يمكنك استخدام المعلمات الافتراضية

function Test(arg1 = 'Hello', arg2 = 'World!'){
  alert(arg1 + ' ' +arg2);
}

Test('Hello', 'World!'); // Hello World!
Test('Hello'); // Hello World!
Test(); // Hello World!


لماذا لا تستخدم !! المشغل أو العامل؟ هذا المشغل ، الذي تم وضعه قبل المتغير ، يحوله إلى منطقي (إذا فهمته جيدًا) ، لذا !!undefined و !!null (وحتى !!NaN ، الذي يمكن أن يكون مثيرًا للاهتمام) سيعود false .

هنا هو مثال:

function foo(bar){
    console.log(!!bar);
}

foo("hey") //=> will log true

foo() //=> will log false

url = url === undefined ? location.href : url;

هناك عدة طرق مختلفة للتحقق مما إذا تم تمرير حجة إلى وظيفة. بالإضافة إلى الاثنين اللذين ذكرتهما في السؤال (الأصلي) - التحقق من arguments.length أو باستخدام || المشغل لتوفير القيم الافتراضية - يمكن للمرء أيضا التحقق بوضوح من الحجج لعدم undefined عن طريق argument2 === undefined أو typeof argument2 === 'undefined' إذا كان واحد هو بجنون العظمة (انظر التعليقات).

باستخدام || أصبح المشغل ممارسة قياسية - كل الأطفال الرائعين يفعلون ذلك - ولكن كن حذرا: سيتم تشغيل القيمة الافتراضية إذا تم تقييم الوسيطة إلى false ، مما يعني أنها قد تكون في الواقع undefined ، null ، false ، 0 ، '' (أو أي شيء آخر التي Boolean(...) إرجاع false ).

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

يعرض التحقق من arguments.length السلوك "الأكثر صحة" ، ولكن قد لا يكون ممكناً إذا كان هناك أكثر من وسيطة اختيارية واحدة.

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

استخدام || قد يقوم المشغل بتشغيل الاستخدام للقيمة الافتراضية حتى إذا تم توفير وسيطة صحيحة. من ناحية أخرى ، قد يكون سلوكه مرغوبًا في الواقع.

للتلخيص: استخدمه فقط إذا كنت تعرف ما تفعله!

في رأيي ، باستخدام || هو أيضًا طريقة الانتقال إذا كان هناك أكثر من وسيطة اختيارية واحدة ولا ترغب في تمرير حرفية للكائن كحل بديل للمعلمات المسماة.

طريقة أخرى لطيفة لتوفير القيم الافتراضية باستخدام arguments.length ممكن من خلال الوقوع من خلال تسميات بيان التبديل:

function test(requiredArg, optionalArg1, optionalArg2, optionalArg3) {
    switch(arguments.length) {
        case 1: optionalArg1 = 'default1';
        case 2: optionalArg2 = 'default2';
        case 3: optionalArg3 = 'default3';
        case 4: break;
        default: throw new Error('illegal argument count')
    }
    // do stuff
}

هذا الجانب السلبي هو أن نية المبرمج ليست (بصريًا) واضحة وتستخدم "الأرقام السحرية". ولذلك فمن المحتمل أن يكون الخطأ عرضة.


يمكن أن يكون ملائماً اقتراب اكتشاف الحجة عن طريق استحضار وظيفتك مع كائن من الخصائص الاختيارية:

function foo(options) {
    var config = { // defaults
        list: 'string value',
        of: [a, b, c],
        optional: {x: y},
        objects: function(param){
           // do stuff here
        }
    }; 
    if(options !== undefined){
        for (i in config) {
            if (config.hasOwnProperty(i)){
                if (options[i] !== undefined) { config[i] = options[i]; }
            }
        }
    }
}

هذه واحدة من الحالات القليلة التي أجد فيها الاختبار:

if(! argument2) {  

}

يعمل بشكل جيد للغاية وينطوي على ضمني صحيح syntactically.

(مع التقييد المتزامن بأنني لن أسمح لقيمة null الشرعية argument2 التي لها معنى آخر ؛ ولكن هذا سيكون مربكًا حقاً ).

تصحيح:

هذا مثال جيد بالفعل على الفرق الأسلوبي بين اللغات المكتوبة بشكل فضفاض والمكتوبة. وخيار الأسلوب الذي يوفره javascript في البستوني.

تفضلي الشخصي (مع عدم وجود أي نقد موجه لتفضيلات أخرى) هو بساطتها. وكلما قل الكود ، طالما أنني متواصل ومختصر ، كلما قل شخص آخر ليتمكن من فهم معني بشكل صحيح.

أحد الآثار المترتبة على هذا التفضيل هو أنني لا أريد - ولا أجد أنه من المفيد - تكديس مجموعة من اختبارات الاعتماد على النوع. بدلاً من ذلك ، أحاول جعل الشفرة تعني ما يبدو أنه يعني ؛ واختبر فقط ما سأحتاج حقًا لاختباره.

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

(أعتبر أن الجانب السلبي في الطريقة التي يستخدمها هؤلاء الناس يستخدمون لغات ديناميكية. في كثير من الأحيان لا يرغب الناس في التخلي عن جميع الاختبارات الثابتة ، وينتهي بهم المطاف إلى تزويرها).

لقد رأيت ذلك بشكل أكثر وضوحًا في مقارنة الأكواد البرمجية ActionScript 3 الشاملة مع شفرة جافا سكريبت الأنيقة. يمكن أن يكون AS3 3 أو 4 أضعاف حجم الشبيبة ، والموثوقية التي أظن أنها ليست أفضل على الإطلاق ، فقط بسبب عدد (3-4X) من قرارات التشفير التي تم إجراؤها.

كما تقول ، Shog9 ، YMMV. :د


إذا كنت تستخدم jQuery ، فإن أحد الخيارات اللطيفة (خاصة في الحالات المعقدة) هو استخدام طريقة تمديد jQuery .

function foo(options) {

    default_options = {
        timeout : 1000,
        callback : function(){},
        some_number : 50,
        some_text : "hello world"
    };

    options = $.extend({}, default_options, options);
}

إذا قمت باستدعاء الوظيفة ، فعليك القيام بما يلي:

foo({timeout : 500});

سيكون متغير الخيارات حينئذ:

{
    timeout : 500,
    callback : function(){},
    some_number : 50,
    some_text : "hello world"
};




arguments