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

Это работает для меня (используйте «По умолчанию» вместо «UTF8»):

$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "Default" $MyPath

Результатом является ASCII без спецификации.

794
задан Peter Mortensen 23 January 2018 в 09:18
поделиться

7 ответов

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

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

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

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

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

1046
ответ дан Paul Dixon 23 January 2018 в 09:18
поделиться

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

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

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

doSomething(); //"defaultValue"
doSomething("myvalue"); //"myvalue"
2
ответ дан Kulbhushan Singh 23 January 2018 в 09:18
поделиться

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

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 .

4
ответ дан Peter Mortensen 23 January 2018 в 09:18
поделиться

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

/**
 * 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 конструктор).
  • Дочерние объекты в иерархиях наследования могут настроить аргументы в пользу своего родительского конструктора, как они считают целесообразным, осуществляя их собственные значения по умолчанию или удостоверяясь, что определенное значение будет всегда использоваться.
13
ответ дан Jonny Buchanan 23 January 2018 в 09:18
поделиться

Можно использовать некоторые различные схемы этого. Я всегда тестировал на arguments.length:

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

  ...

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

И затем Paul предоставил один провальный сценарий!-)

18
ответ дан Peter Mortensen 23 January 2018 в 09:18
поделиться

Если необходимо зажать литерал 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];

    // ...
}
44
ответ дан Oli 23 January 2018 в 09:18
поделиться

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

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));
2
ответ дан Bart Wttewaall 23 January 2018 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: