Вопрос:

Есть ли лучший способ сделать необязательные параметры функции в JavaScript?

javascript function arguments

372404 просмотра

28 ответа

95447 Репутация автора

На этот вопрос уже есть ответ здесь:

Я всегда обрабатывал необязательные параметры в JavaScript так:

function myFunc(requiredArg, optionalArg){
  optionalArg = optionalArg || 'defaultValue';

  // Do stuff
}

Есть ли лучший способ сделать это?

Есть ли случаи, когда ||такое использование не поможет?

Автор: Mark Biek Источник Размещён: 29.09.2008 02:27

Ответы (28)


1042 плюса

249075 Репутация автора

Решение

Ваша логика терпит неудачу, если optionArg передается, но оценивается как ложное - попробуйте это как альтернативу

if (typeof optionalArg === 'undefined') { optionalArg = 'default'; }

Или альтернативная идиома:

optionalArg = (typeof optionalArg === 'undefined') ? 'default' : optionalArg;

Используйте любую идиому, которая сообщит вам наилучшие намерения!

Автор: Paul Dixon Размещён: 29.09.2008 02:30

17 плюса

2130 Репутация автора

Вы можете использовать несколько разных схем для этого. Я всегда проверял аргументы. Длина:

function myFunc(requiredArg, optionalArg){
  optionalArg = myFunc.arguments.length<2 ? 'defaultValue' : optionalArg;

  ...

- делая это, он не может потерпеть неудачу, но я не знаю, есть ли у вашего пути шанс потерпеть неудачу, просто сейчас я не могу придумать сценарий, в котором он действительно потерпит неудачу ...

И тогда Павел предоставил один неудачный сценарий! -)

Автор: roenving Размещён: 29.09.2008 02:33

44 плюса

123000 Репутация автора

Если вам нужно вставить буквальное значение NULL, у вас могут возникнуть некоторые проблемы. Кроме того, нет, я думаю, что вы, вероятно, на правильном пути.

Другой метод, который выбирают некоторые люди, - это использование массива переменных, повторяющихся в списке аргументов. Это выглядит немного аккуратнее, но я думаю, что это немного (очень немного) более интенсивно процесс / память.

function myFunction (argArray) {
    var defaults = {
        'arg1'  :   "value 1",
        'arg2'  :   "value 2",
        'arg3'  :   "value 3",
        'arg4'  :   "value 4"
    }

    for(var i in defaults) 
        if(typeof argArray[i] == "undefined") 
               argArray[i] = defaults[i];

    // ...
}
Автор: Oli Размещён: 29.09.2008 02:34

13 плюса

51245 Репутация автора

Подобно ответу Оли, я использую аргумент Object и Object, который определяет значения по умолчанию. С небольшим количеством сахара ...

/**
 * Updates an object's properties with other objects' properties. All
 * additional non-falsy arguments will have their properties copied to the
 * destination object, in the order given.
 */
function extend(dest) {
  for (var i = 1, l = arguments.length; i < l; i++) {
    var src = arguments[i]
    if (!src) {
      continue
    }
    for (var property in src) {
      if (src.hasOwnProperty(property)) {
        dest[property] = src[property]
      }
    }
  }
  return dest
}

/**
 * Inherit another function's prototype without invoking the function.
 */
function inherits(child, parent) {
  var F = function() {}
  F.prototype = parent.prototype
  child.prototype = new F()
  child.prototype.constructor = child
  return child
}

... это можно сделать немного лучше.

function Field(kwargs) {
  kwargs = extend({
    required: true, widget: null, label: null, initial: null,
    helpText: null, errorMessages: null
  }, kwargs)
  this.required = kwargs.required
  this.label = kwargs.label
  this.initial = kwargs.initial
  // ...and so on...
}

function CharField(kwargs) {
  kwargs = extend({
    maxLength: null, minLength: null
  }, kwargs)
  this.maxLength = kwargs.maxLength
  this.minLength = kwargs.minLength
  Field.call(this, kwargs)
}
inherits(CharField, Field)

Что хорошего в этом методе?

  • Вы можете опустить столько аргументов, сколько захотите - если вы хотите переопределить значение только одного аргумента, вы можете просто предоставить этот аргумент вместо того, чтобы явно передавать его undefined, скажем, есть 5 аргументов, и вы хотите настроить только последний один, как вы могли бы сделать с некоторыми из других методов, предложенных.
  • При работе с функцией конструктора для объекта, который наследуется от другого, легко принять любые аргументы, которые требуются конструктору объекта, от которого вы наследуете, так как вам не нужно называть эти аргументы в сигнатуре конструктора, или даже предоставить свои собственные значения по умолчанию (пусть конструктор родительского объекта сделает это за вас, как показано выше, когда CharFieldвызывает Fieldконструктор вызовов ).
  • Дочерние объекты в иерархиях наследования могут настраивать аргументы для своего родительского конструктора по своему усмотрению, применяя свои собственные значения по умолчанию или гарантируя, что определенное значение всегда будет использоваться.
Автор: Jonny Buchanan Размещён: 29.09.2008 11:16

125 плюса

18113 Репутация автора

Я считаю, что это самый простой, самый читаемый способ:

if (typeof myVariable === 'undefined') { myVariable = 'default'; }
//use myVariable here

Ответ Пола Диксона (по моему скромному мнению) менее читабелен, чем этот, но все сводится к предпочтениям.

Ответ Инсина намного сложнее, но гораздо полезнее для больших функций!

РЕДАКТИРОВАНИЕ 17.11.2013 21:33: я создал пакет для Node.js, который облегчает "перегрузку" функций (методов), называемых параметрическими .

Автор: trusktr Размещён: 14.11.2011 09:23

32 плюса

17201 Репутация автора

В идеале вы должны выполнить рефакторинг для передачи объекта и слияния его с объектом по умолчанию, поэтому порядок передачи аргументов не имеет значения (см. Второй раздел этого ответа ниже).

Однако, если вы просто хотите что-то быстрое, надежное, простое в использовании и не громоздкое, попробуйте следующее:


Чистое быстрое исправление для любого количества аргументов по умолчанию

  • Он элегантно масштабируется: минимальный дополнительный код для каждого нового значения по умолчанию
  • Вы можете вставить его куда угодно: просто измените количество необходимых аргументов и переменных
  • Если вы хотите передать undefinedаргумент со значением по умолчанию, таким образом, переменная устанавливается как undefined. Большинство других параметров на этой странице заменит undefinedзначение по умолчанию.

Вот пример для предоставления значений по умолчанию для трех необязательных аргументов (с двумя обязательными аргументами)

function myFunc( requiredA, requiredB,  optionalA, optionalB, optionalC ) {

  switch (arguments.length - 2) { // 2 is the number of required arguments
    case 0:  optionalA = 'Some default';
    case 1:  optionalB = 'Another default';
    case 2:  optionalC = 'Some other default';
    // no breaks between cases: each case implies the next cases are also needed
  }

}

Простая демка . Это похоже на ответ roenving , но легко расширяется для любого количества аргументов по умолчанию, его легче обновлять, а использовать argumentsнетFunction.arguments .


Передача и объединение объектов для большей гибкости

Приведенный выше код, как и многие другие способы создания аргументов по умолчанию, не может передавать аргументы вне последовательности, например, передавая, optionalCно оставляя optionalBзначение по умолчанию.

Хорошим вариантом для этого является передача объектов и слияние с объектом по умолчанию. Это также хорошо для удобства сопровождения (просто позаботьтесь о том, чтобы ваш код читался, чтобы будущие соавторы не оставляли догадываться о возможном содержании объектов, которые вы передаете).

Пример использования jQuery. Если вы не используете jQuery, вы можете вместо этого использовать Underscore _.defaults(object, defaults)или просмотреть эти параметры :

function myFunc( args ) {
  var defaults = {
    optionalA: 'Some default',
    optionalB: 'Another default',
    optionalC: 'Some other default'
  };
  args = $.extend({}, defaults, args);
}

Вот простой пример этого в действии .

Автор: user568458 Размещён: 20.02.2012 03:36

8 плюса

10656 Репутация автора

Если вы широко используете значения по умолчанию, это кажется гораздо более читабельным:

function usageExemple(a,b,c,d){
    //defaults
    a=defaultValue(a,1);
    b=defaultValue(b,2);
    c=defaultValue(c,4);
    d=defaultValue(d,8);

    var x = a+b+c+d;
    return x;
}

Просто объявите эту функцию в глобальной области видимости.

function defaultValue(variable,defaultValue){
    return(typeof variable!=='undefined')?(variable):(defaultValue);
}

Шаблон использования fruit = defaultValue(fruit,'Apple');

* PS вы можете переименовать defaultValueфункцию в короткое имя, только не используйте defaultэто зарезервированное слово в javascript.

Автор: Vitim.us Размещён: 15.05.2012 09:23

132 плюса

1982 Репутация автора

В ECMAScript 2015 (он же ES6) вы можете объявить значения аргументов по умолчанию в объявлении функции:

function myFunc(requiredArg, optionalArg = 'defaultValue') {
    // do stuff
}

Подробнее о них в этой статье на MDN .

В настоящее время это поддерживается только Firefox , но, поскольку стандарт уже завершен, ожидается быстрое улучшение поддержки.

РЕДАКТИРОВАТЬ (2019-06-12):

Параметры по умолчанию теперь широко поддерживаются современными браузерами. Все версии Internet Explorer не поддерживают эту функцию. Однако Chrome, Firefox и Edge в настоящее время поддерживают его.

Автор: Lachlan Hunt Размещён: 19.02.2013 01:13

0 плюса

5148 Репутация автора

Поправьте меня, если я ошибаюсь, но это кажется самым простым способом (во всяком случае, для одного аргумента):

function myFunction(Required,Optional)
{
    if (arguments.length<2) Optional = "Default";
    //Your code
}
Автор: Brian McCutchon Размещён: 21.02.2013 02:03

-1 плюса

2145 Репутация автора

Я предлагаю вам использовать ArgueJS следующим образом:

function myFunc(){
  arguments = __({requiredArg: undefined, optionalArg: [undefined: 'defaultValue'})

  //do stuff, using arguments.requiredArg and arguments.optionalArg
  //    to access your arguments

}

Вы также можете заменить undefinedтип аргумента, который вы ожидаете получить, например:

function myFunc(){
  arguments = __({requiredArg: Number, optionalArg: [String: 'defaultValue'})

  //do stuff, using arguments.requiredArg and arguments.optionalArg
  //    to access your arguments

}
Автор: zVictor Размещён: 12.04.2013 03:35

2 плюса

2986 Репутация автора

Я не знаю, почему ответ @ Paul отрицателен, но проверка null- хороший выбор. Может быть, более позитивный пример будет иметь смысл:

В JavaScript пропущенный параметр похож на объявленную переменную, которая не инициализируется (просто var a1;). А оператор равенства преобразует неопределенное в нулевое, так что это прекрасно работает как с типами значений, так и с объектами, и именно так CoffeeScript обрабатывает необязательные параметры.

function overLoad(p1){
    alert(p1 == null); // Caution, don't use the strict comparison: === won't work.
    alert(typeof p1 === 'undefined');
}

overLoad(); // true, true
overLoad(undefined); // true, true. Yes, undefined is treated as null for equality operator.
overLoad(10); // false, false


function overLoad(p1){
    if (p1 == null) p1 = 'default value goes here...';
    //...
}

Тем не менее, есть опасения, что для лучшей семантики typeof variable === 'undefined'это немного лучше. Я не собираюсь защищать это, поскольку в основе API лежит вопрос о том, как реализована функция; это не должно интересовать пользователя API.

Я также должен добавить, что это единственный способ физически убедиться, что любой аргумент был пропущен, используя inоператор, который, к сожалению, не будет работать с именами параметров, поэтому должен передавать индекс arguments.

function foo(a, b) {
    // Both a and b will evaluate to undefined when used in an expression
    alert(a); // undefined
    alert(b); // undefined

    alert("0" in arguments); // true
    alert("1" in arguments); // false
}

foo (undefined);
Автор: Arman McHitarian Размещён: 07.05.2013 01:31

2 плюса

384 Репутация автора

Проверка на undefined не нужна и не так надежна, как могла бы быть, потому что, как указал user568458, предоставленное решение завершается неудачно, если передано значение null или false. Пользователи вашего API могут подумать, что false или null заставит метод избегать этого параметра.

function PaulDixonSolution(required, optionalArg){
   optionalArg = (typeof optionalArg === "undefined") ? "defaultValue" : optionalArg;
   console.log(optionalArg);
};
PaulDixonSolution("required");
PaulDixonSolution("required", "provided");
PaulDixonSolution("required", null);
PaulDixonSolution("required", false);

Результат:

defaultValue
provided
null
false

Последние два потенциально плохие. Вместо этого попробуйте:

function bulletproof(required, optionalArg){
   optionalArg = optionalArg ? optionalArg : "defaultValue";;
   console.log(optionalArg);
};
bulletproof("required");
bulletproof("required", "provided");
bulletproof("required", null);
bulletproof("required", false);

Что приводит к:

defaultValue
provided
defaultValue
defaultValue

Единственный сценарий, когда это не является оптимальным, - это когда у вас есть необязательные параметры, которые должны быть логическими или преднамеренными нулевыми.

Автор: slartibartfast Размещён: 27.09.2013 05:15

0 плюса

3846 Репутация автора

Те, которые короче, чем версия оператора typeof.

function foo(a, b) {
    a !== undefined || (a = 'defaultA');
    if(b === undefined) b = 'defaultB';
    ...
}
Автор: Aurélien Ooms Размещён: 07.11.2013 06:05

1 плюс

1407 Репутация автора

Вот чем я закончил:

function WhoLikesCake(options) {
  options = options || {};
  var defaultOptions = {
    a : options.a || "Huh?",
    b : options.b || "I don't like cake."
  }
  console.log('a: ' + defaultOptions.b + ' - b: ' + defaultOptions.b);

  // Do more stuff here ...
}

Вызывается так:

WhoLikesCake({ b : "I do" });
Автор: NinjaFart Размещён: 29.11.2013 09:04

4 плюса

3436 Репутация автора

Я привык видеть несколько основных вариантов обработки необязательных переменных. Иногда расслабленные версии полезны.

function foo(a, b, c) {
  a = a || "default";   // Matches 0, "", null, undefined, NaN, false.
  a || (a = "default"); // Matches 0, "", null, undefined, NaN, false.

  if (b == null) { b = "default"; } // Matches null, undefined.

  if (typeof c === "undefined") { c = "default"; } // Matches undefined.
}

Ложное значение по умолчанию, используемое с переменной a, например, широко используется в Backbone.js .

Автор: Matt Montag Размещён: 13.03.2014 06:27

-2 плюса

2149 Репутация автора

function foo(requiredArg){
  if(arguments.length>1) var optionalArg = arguments[1];
}
Автор: Dustin Poissant Размещён: 09.04.2014 02:03

1 плюс

11 Репутация автора

Народ -

Посмотрев на эти и другие решения, я опробовал ряд из них, используя в качестве основы фрагмент кода, изначально взятый из W3Schools. Вы можете найти то, что работает в следующем. Каждый из пунктов также прокомментировал работу и позволяет вам экспериментировать, просто удаляя отдельные комментарии. Чтобы быть понятным, это параметр "colorcolor", который не определен.

function person(firstname, lastname, age, eyecolor)
{
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
this.eyecolor = eyecolor;
// if(null==eyecolor)
//   this.eyecolor = "unknown1";
//if(typeof(eyecolor)==='undefined') 
//   this.eyecolor = "unknown2";
// if(!eyecolor)
//   this.eyecolor = "unknown3";
this.eyecolor = this.eyecolor || "unknown4";
}

var myFather = new person("John", "Doe", 60);
var myMother = new person("Sally", "Rally", 48, "green");

var elem = document.getElementById("demo");
elem.innerHTML = "My father " +
              myFather.firstname + " " +
              myFather.lastname + " is " +
              myFather.age + " with " +
              myFather.eyecolor + " eyes.<br/>" +
              "My mother " +
              myMother.firstname + " " +
              myMother.lastname + " is " +
              myMother.age + " with " +
              myMother.eyecolor + " eyes."; 
Автор: Mark Funk Размещён: 13.04.2014 08:53

2 плюса

938 Репутация автора

Я попробовал некоторые варианты, упомянутые здесь, и тестировал их производительность. В этот момент логика кажется самой быстрой. Хотя со временем это может измениться (разные версии движка JavaScript).

Вот мои результаты (Microsoft Edge 20.10240.16384.0):

Function executed            Operations/sec     Statistics
TypeofFunction('test');          92,169,505     ±1.55%   9% slower
SwitchFuntion('test');            2,904,685     ±2.91%  97% slower
ObjectFunction({param1: 'test'});   924,753     ±1.71%  99% slower
LogicalOrFunction('test');      101,205,173     ±0.92%     fastest
TypeofFunction2('test');         35,636,836     ±0.59%  65% slower

Этот тест производительности можно легко повторить на: http://jsperf.com/optional-parameters-typeof-vs-switch/2

Это код теста:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        function TypeofFunction(param1, optParam1, optParam2, optParam3) {
            optParam1 = (typeof optParam1 === "undefined") ? "Some default" : optParam1;
            optParam2 = (typeof optParam2 === "undefined") ? "Another default" : optParam2;
            optParam3 = (typeof optParam3 === "undefined") ? "Some other default" : optParam3;
        }

        function TypeofFunction2(param1, optParam1, optParam2, optParam3) {
            optParam1 = defaultValue(optParam1, "Some default");
            optParam2 = defaultValue(optParam2, "Another default");
            optParam3 = defaultValue(optParam3, "Some other default");
        }

        function defaultValue(variable, defaultValue) {
            return (typeof variable !== 'undefined') ? (variable) : (defaultValue);
        }

        function SwitchFuntion(param1, optParam1, optParam2, optParam3) {
            switch (arguments.length - 1) { // <-- 1 is number of required arguments
                case 0:
                    optParam1 = 'Some default';
                case 1:
                    optParam2 = 'Another default';
                case 2:
                    optParam3 = 'Some other default';
            }
        }

        function ObjectFunction(args) {
            var defaults = {
                optParam1: 'Some default',
                optParam2: 'Another default',
                optParam3: 'Some other default'
            }
            args = $.extend({}, defaults, args);
        }

        function LogicalOrFunction(param1, optParam1, optParam2, optParam3) {
            optParam1 || (optParam1 = 'Some default');
            optParam2 || (optParam1 = 'Another default');
            optParam3 || (optParam1 = 'Some other default');
        }
    };
</script>
Автор: JDC Размещён: 19.06.2014 11:25

3 плюса

4853 Репутация автора

Если вы используете библиотеку Underscore (вам следует, это потрясающая библиотека):

_.defaults(optionalArg, 'defaultValue');
Автор: roo2 Размещён: 22.09.2014 11:59

1 плюс

1400 Репутация автора

function Default(variable, new_value)
{
    if(new_value === undefined) { return (variable === undefined) ? null : variable; }
    return (variable === undefined) ? new_value : variable;
}

var a = 2, b = "hello", c = true, d;

var test = Default(a, 0),
test2 = Default(b, "Hi"),
test3 = Default(c, false),
test4 = Default(d, "Hello world");

window.alert(test + "\n" + test2 + "\n" + test3 + "\n" + test4);

http://jsfiddle.net/mq60hqrf/

Автор: Imagine Breaker Размещён: 03.10.2014 09:28

8 плюса

1609 Репутация автора

Свободная проверка типа

Легко писать, но 0, '', false, nullи undefinedбудут преобразованы в значение по умолчанию, которое не может быть ожидаемый результат.

function myFunc(requiredArg, optionalArg) {
    optionalArg = optionalArg || 'defaultValue';
}

Строгая проверка типов

Дольше, но покрывает большинство случаев. Единственный случай, когда он неправильно назначает значение по умолчанию, - это когда мы передаем в undefinedкачестве параметра.

function myFunc(requiredArg, optionalArg) {
    optionalArg = typeof optionalArg !== 'undefined' ? optionalArg : 'defaultValue';
}

Проверка аргументов переменной

Ловит все дела, но писать неуклюже.

function myFunc(requiredArg, optionalArg1, optionalArg2) {
    optionalArg1 = arguments.length > 1 ? optionalArg1 : 'defaultValue';
    optionalArg2 = arguments.length > 2 ? optionalArg2 : 'defaultValue';
}

ES6

К сожалению, в данный момент браузер очень плохо поддерживает

function myFunc(requiredArg, optionalArg = 'defaultValue') {

}
Автор: Petr Hurtak Размещён: 15.05.2015 01:46

2 плюса

526 Репутация автора

Пришёл к этому вопросу, ища параметры по умолчанию в EcmaScript 2015 , таким образом, просто упомянув ...

С ES6 мы можем сделать параметры по умолчанию :

function doSomething(optionalParam = "defaultValue"){
    console.log(optionalParam);//not required to check for falsy values
}

doSomething(); //"defaultValue"
doSomething("myvalue"); //"myvalue"
Автор: Kulbhushan Singh Размещён: 09.10.2015 02:19

5 плюса

2426 Репутация автора

С ES2015 / ES6 вы можете воспользоваться тем, Object.assignчто может заменить $.extend()или_.defaults()

function myFunc(requiredArg, options = {}) {
  const defaults = {
    message: 'Hello',
    color: 'red',
    importance: 1
  };

  const settings = Object.assign({}, defaults, options);

  // do stuff
}

Вы также можете использовать аргументы по умолчанию, как это

function myFunc(requiredArg, { message: 'Hello', color: 'red', importance: 1 } = {}) {
  // do stuff
}
Автор: Yann Bertrand Размещён: 01.02.2016 11:09

2 плюса

21 Репутация автора

Во время проекта я заметил, что слишком много повторюсь с необязательными параметрами и настройками, поэтому я создал класс, который обрабатывает проверку типов и присваивает значение по умолчанию, что приводит к аккуратному и читабельному коду. Посмотрите пример и дайте мне знать, если это работает для вас.

var myCar           = new Car('VW', {gearbox:'automatic', options:['radio', 'airbags 2x']});
var myOtherCar      = new Car('Toyota');

function Car(brand, settings) {
    this.brand      = brand;

    // readable and adjustable code
    settings        = DefaultValue.object(settings, {});
    this.wheels     = DefaultValue.number(settings.wheels, 4);
    this.hasBreaks  = DefaultValue.bool(settings.hasBreaks, true);
    this.gearbox    = DefaultValue.string(settings.gearbox, 'manual');
    this.options    = DefaultValue.array(settings.options, []);

    // instead of doing this the hard way
    settings        = settings || {};
    this.wheels     = (!isNaN(settings.wheels)) ? settings.wheels : 4;
    this.hasBreaks  = (typeof settings.hasBreaks !== 'undefined') ? (settings.hasBreaks === true) : true;
    this.gearbox    = (typeof settings.gearbox === 'string') ? settings.gearbox : 'manual';
    this.options    = (typeof settings.options !== 'undefined' && Array.isArray(settings.options)) ? settings.options : [];
}

Используя этот класс:

(function(ns) {

    var DefaultValue = {

        object: function(input, defaultValue) {
            if (typeof defaultValue !== 'object') throw new Error('invalid defaultValue type');
            return (typeof input !== 'undefined') ? input : defaultValue;
        },

        bool: function(input, defaultValue) {
            if (typeof defaultValue !== 'boolean') throw new Error('invalid defaultValue type');
            return (typeof input !== 'undefined') ? (input === true) : defaultValue;
        },

        number: function(input, defaultValue) {
            if (isNaN(defaultValue)) throw new Error('invalid defaultValue type');
            return (typeof input !== 'undefined' && !isNaN(input)) ? parseFloat(input) : defaultValue;
        },

        // wrap the input in an array if it is not undefined and not an array, for your convenience
        array: function(input, defaultValue) {
            if (typeof defaultValue === 'undefined') throw new Error('invalid defaultValue type');
            return (typeof input !== 'undefined') ? (Array.isArray(input) ? input : [input]) : defaultValue;
        },

        string: function(input, defaultValue) {
            if (typeof defaultValue !== 'string') throw new Error('invalid defaultValue type');
            return (typeof input === 'string') ? input : defaultValue;
        },

    };

    ns.DefaultValue = DefaultValue;

}(this));
Автор: Bart Wttewaall Размещён: 23.03.2016 10:52

1 плюс

259 Репутация автора

Вот мое решение. При этом вы можете оставить любой параметр, который вы хотите. Порядок необязательных параметров не важен, и вы можете добавить пользовательскую проверку.

function YourFunction(optionalArguments) {
            //var scope = this;

            //set the defaults
            var _value1 = 'defaultValue1';
            var _value2 = 'defaultValue2';
            var _value3 = null;
            var _value4 = false;

            //check the optional arguments if they are set to override defaults...
            if (typeof optionalArguments !== 'undefined') {

                if (typeof optionalArguments.param1 !== 'undefined')
                    _value1 = optionalArguments.param1;

                if (typeof optionalArguments.param2 !== 'undefined')
                    _value2 = optionalArguments.param2;

                if (typeof optionalArguments.param3 !== 'undefined')
                    _value3 = optionalArguments.param3;

                if (typeof optionalArguments.param4 !== 'undefined')
                    //use custom parameter validation if needed, in this case for javascript boolean
                   _value4 = (optionalArguments.param4 === true || optionalArguments.param4 === 'true');
            }

            console.log('value summary of function call:');
            console.log('value1: ' + _value1);
            console.log('value2: ' + _value2);
            console.log('value3: ' + _value3);
            console.log('value4: ' + _value4);
            console.log('');
        }


        //call your function in any way you want. You can leave parameters. Order is not important. Here some examples:
        YourFunction({
            param1: 'yourGivenValue1',
            param2: 'yourGivenValue2',
            param3: 'yourGivenValue3',
            param4: true,
        });

        //order is not important
        YourFunction({
            param4: false,
            param1: 'yourGivenValue1',
            param2: 'yourGivenValue2',
        });

        //uses all default values
        YourFunction();

        //keeps value4 false, because not a valid value is given
        YourFunction({
            param4: 'not a valid bool'
        });
Автор: Duco L Размещён: 11.04.2016 01:51

1 плюс

6045 Репутация автора

  1. arg || 'default' это отличный способ и работает в 90% случаев

  2. Сбой, когда вам нужно передать значения, которые могут быть «ложными»

    • false
    • 0
    • NaN
    • ""

    В этих случаях вам нужно быть более многословным и проверять наличие undefined

  3. Также будьте осторожны, когда у вас есть дополнительные аргументы, вы должны знать типы всех ваших аргументов.

Автор: mcfedr Размещён: 30.04.2016 07:36

1 плюс

41 Репутация автора

Во всех случаях, когда optionArg является ложным, вы получите defaultValue.

function myFunc(requiredArg, optionalArg) {
    optionalArg = optionalArg || 'defaultValue';
    console.log(optionalArg);
    // Do stuff
}
myFunc(requiredArg);
myFunc(requiredArg, null);
myFunc(requiredArg, undefined);
myFunc(requiredArg, "");
myFunc(requiredArg, 0);
myFunc(requiredArg, false);

Все вышеперечисленные журналы defaultValue, потому что все 6 являются ложными. В случаях 4, 5, 6 вам может быть не интересно устанавливать опциональное значение Arg как defaultValue, но оно устанавливается, поскольку они ложные.

Автор: Pavan Varanasi Размещён: 02.09.2016 04:16

-1 плюса

2817 Репутация автора

Похоже, что самый безопасный способ - разобраться со всеми \ любыми ложными типами предоставленных аргументов перед тем, как принять решение использовать значение по умолчанию, - это проверить наличие / наличие необязательного аргумента в вызываемой функции.

Полагаясь на создание члена объекта arguments, который даже не создается, если аргумент отсутствует, независимо от того, может ли он быть объявлен, мы можем написать вашу функцию следующим образом:

  function myFunc(requiredArg, optionalArg){
        optionalArg = 1 in arguments ? optionalArg : 'defaultValue';
  //do stuff
  }

Используя это поведение: мы можем безопасно проверять любые пропущенные значения в списке аргументов произвольно и явно, когда нам нужно убедиться, что функция получает определенное значение, требуемое в ее процедуре.

В следующем демонстрационном коде мы намеренно поместим типизированное и бесценное неопределенное значение в качестве значения по умолчанию, чтобы можно было определить, может ли оно произойти сбой при ложных значениях аргумента, таких как 0 false и т. Д., Или же оно будет вести себя как ожидалось.

function argCheck( arg1, arg2, arg3 ){

       arg1 = 0 in arguments || undefined;
       arg2 = 1 in arguments || false;
       arg3 = 2 in arguments || 0;
   var arg4 = 3 in arguments || null;

   console.log( arg1, arg2, arg3, arg4 ) 
}

Теперь проверяем несколько ложных значений аргументов, чтобы увидеть, правильно ли обнаружено их присутствие и, следовательно, оценивается как true :

argCheck( "", 0, false, null );
>> true true true true

Это означает, что они не потерпели неудачу в признании / как ожидаемые значения аргумента. Здесь у нас есть проверка со всеми отсутствующими аргументами, которая согласно нашему алгоритму должна получать значения по умолчанию, даже если они ложные .

argCheck( );
>> undefined false 0 null

Как мы видим, аргументы arg1, arg2, arg3 и необъявленный arg4 возвращают свои точные значения по умолчанию , как указано . Поскольку теперь мы убедились, что это работает, мы можем переписать функцию, которая фактически сможет использовать их, как в первом примере, используя: либо if, либо троичное условие.

В функциях, которые имеют более одного необязательного аргумента - проходной цикл, мог бы сэкономить нам несколько битов. Но поскольку имена аргументов не инициализируются, если их значения не указаны, мы не можем получить к ним доступ по именам, даже если мы программно записали значение по умолчанию, мы можем получить к ним доступ только по аргументам [index], что бесполезно для читабельности кода.

Но помимо этого неудобства, которое в определенных ситуациях кодирования может быть вполне приемлемым, существует еще одна неучтенная проблема для нескольких и произвольного числа значений аргументов по умолчанию. Что может и должно считаться ошибкой, поскольку мы больше не можем пропускать аргументы, как мы когда-то могли без указания значения использовать такой синтаксис, как:

argCheck("a",,22,{});

потому что это бросит! Что делает невозможным замену нашего аргумента конкретным ложным типом желаемого значения по умолчанию. Что глупо, так как объект arguments является массивоподобным объектом и, как ожидается, будет поддерживать этот синтаксис и соглашение как есть, изначально или по умолчанию!

Из-за этого близорукого решения мы больше не можем надеяться написать такую ​​функцию:

function argCheck( ) {
    var _default = [undefined, 0, false, null ],
        _arg = arguments;

 for( var x in _default ) {
         x in _arg ? 1 : _arg[x] = _default[x];
        }
    console.log( _arg[0],_arg[1],_arg[2],_arg[3] );
}

в этом случае мы сможем записать каждое значение по умолчанию желаемого типа в строку аргументов и по крайней мере получить к ним доступ через args.index.

Например, этот вызов функции даст:

argCheck();
>>undefined 0 false null

как определено в нашем массиве значений аргументов по умолчанию. Однако следующее все еще возможно:

argCheck({})
>>Object {  } 0 false null

argCheck({}, [])
>>Object {  } Array [  ] false null

Но, к сожалению, нет

 argCheck("a",,,22);
 >>SyntaxError: expected expression, got ','

Что в противном случае будет входить в систему:

>>a 0 false 22

но это в лучшем мире! Однако - для первоначального вопроса - самая верхняя функция подойдет. например:

function argCheck( arg, opt ) {
         1 in arguments ? 1 : opt = "default";
         console.log( arg, opt );
}

ps: извините за то, что не сохранил типы выбранных значений по умолчанию во входных данных моего аргумента при их записи.

Автор: Bekim Bacaj Размещён: 29.10.2016 03:44
Вопросы из категории :
32x32