programing tip

JavaScript에서 선택적 함수 매개 변수를 수행하는 더 좋은 방법이 있습니까?

itbloger 2020. 9. 29. 07:22
반응형

JavaScript에서 선택적 함수 매개 변수를 수행하는 더 좋은 방법이 있습니까? [복제]


이 질문에 이미 답변이 있습니다.

저는 항상 다음과 같이 JavaScript에서 선택적 매개 변수를 처리했습니다.

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

  // Do stuff
}

더 나은 방법이 있습니까?

||그런 사용 이 실패하는 경우가 있습니까?


optionalArg가 전달되면 논리가 실패하지만 false로 평가됩니다. 대안으로 시도해보세요.

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

또는 다른 관용구 :

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

의도를 가장 잘 전달하는 관용구를 사용하십시오!


ECMAScript 2015 (일명 "ES6")에서는 함수 선언에 기본 인수 값을 선언 할 수 있습니다.

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

MDN에 대한 이 기사 에서 더 많은 정보를 얻을 수 있습니다 .

이것은 현재 Firefox에서만 지원 되지만 표준이 완성됨에 따라 지원이 빠르게 향상 될 것으로 예상됩니다.

수정 (2019-06-12) :

기본 매개 변수는 이제 최신 브라우저에서 광범위하게 지원됩니다. 모든 버전의 Internet Explorer는이 기능을 지원하지 않습니다. 그러나 현재 Chrome, Firefox 및 Edge에서 지원합니다.


나는 이것이 가장 간단하고 가장 읽기 쉬운 방법이라고 생각합니다.

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

Paul Dixon의 대답 (내 겸손한 의견으로는)은 이것보다 읽기 어렵지만 선호도에 달려 있습니다.

insin의 대답은 훨씬 더 발전되었지만 큰 기능에는 훨씬 더 유용합니다!

편집 11/17/2013 9:33 pm : parametric 이라는 함수 (메소드)를 쉽게 "오버로드"할 수있는 Node.js 용 패키지를 만들었습니다 .


리터럴을 삽입해야하는 경우 NULL몇 가지 문제가있을 수 있습니다. 그 외에는 당신이 올바른 길을 가고 있다고 생각합니다.

일부 사람들이 선택하는 다른 방법은 인수 목록을 반복하는 변수의 assoc 배열을 취하는 것입니다. 좀 더 깔끔해 보이지만 조금 더 프로세스 / 메모리 집약적이라고 생각합니다.

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];

    // ...
}

이상적으로는 개체를 전달 하고 기본 개체와 병합 하도록 리팩터링 하므로 인수가 전달되는 순서는 중요하지 않습니다 (아래 답변의 두 번째 섹션 참조).

그러나 빠르고 안정적이며 사용하기 쉽고 부피가 크지 않은 것을 원한다면 다음을 시도하십시오.


여러 기본 인수에 대한 깔끔한 빠른 수정

  • 우아하게 확장 : 각각의 새로운 기본값에 대한 최소한의 추가 코드
  • 어디에나 붙여 넣을 수 있습니다. 필요한 인수와 변수의 수만 변경하면됩니다.
  • undefined이런 식으로 기본값을 사용하여 인수 에 전달 하려면 변수가로 설정됩니다 undefined. 이 페이지에있는 대부분의 다른 옵션 undefined은 기본값으로 대체 됩니다.

다음은 3 개의 선택적 인수에 대한 기본값을 제공하는 예입니다 (2 개의 필수 인수 포함).

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의 대답 과 비슷하지만 기본 인수 수에 관계없이 쉽게 확장 할 수 있으며 업데이트하기 쉽고 not을 사용argumentsFunction.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);
}

여기 에 간단한 예가 있습니다 .


이를 위해 몇 가지 다른 구성표를 사용할 수 있습니다. 나는 항상 arguments.length를 테스트했습니다.

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

  ...

-그렇게하면 실패 할 수는 없지만 당신의 방식이 실패 할 가능성이 있는지는 모르겠지만, 지금은 실제로 실패 할 시나리오를 생각할 수 없습니다.

그리고 Paul은 하나의 실패한 시나리오를 제공했습니다!-)


Oli의 답변과 유사하게 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).
  • 상속 계층 구조의 자식 개체는 부모 생성자에 대한 인수를 적절하다고 판단하여 사용자 지정하여 고유 한 기본값을 적용하거나 특정 값이 항상 사용되도록 수 있습니다.

기본값을 광범위하게 사용하는 경우 훨씬 더 읽기 쉽습니다.

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;
}

전역 escope에서이 함수를 선언하기 만하면됩니다.

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

사용 패턴 fruit = defaultValue(fruit,'Apple');

* PS 당신은 defaultValue짧은 이름으로 함수의 이름을 바꿀 수 있습니다 default. 자바 스크립트에서 예약어를 사용하지 마십시오 .


느슨한 유형 검사

쉽게 쓸 수 있지만 0, '', false, nullundefined결과를 기대되지 않을 수 있습니다 기본 값으로 변환됩니다.

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') {

}

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
}

선택적 변수 처리에 대한 몇 가지 기본 변형을 보는 데 익숙합니다. 때로는 편안한 버전이 유용합니다.

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 에서 광범위하게 사용됩니다 .


Underscore 라이브러리를 사용하고 있다면 (멋진 라이브러리입니다) :

_.defaults(optionalArg, 'defaultValue');

이 질문에 도착하여 EcmaScript 2015에서 기본 매개 변수를 검색 하여 다음을 언급합니다.

ES6사용하면 기본 매개 변수를 수행 할 수 있습니다 .

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

doSomething(); //"defaultValue"
doSomething("myvalue"); //"myvalue"

프로젝트를 진행하는 동안 선택적 매개 변수와 설정을 너무 많이 반복하고 있다는 것을 알게 되었기 때문에 유형 검사를 처리하고 깔끔하고 읽기 쉬운 코드를 생성하는 기본값을 할당하는 클래스를 만들었습니다. 예제를보고 이것이 당신에게 효과가 있는지 알려주십시오.

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));

@Paul의 답변이 왜 반대 null인지 모르겠지만 유효성 검사 는 좋은 선택입니다. 더 긍정적 인 예가 더 낫습니다.

JavaScript에서 누락 된 매개 변수는 초기화되지 않은 선언 된 변수와 같습니다 (단지 var a1;). 그리고 같음 연산자는 undefined를 null로 변환하므로 값 유형과 객체 모두에서 훌륭하게 작동하며 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);

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

이것이 최적이 아닌 유일한 시나리오는 실제로 부울 또는 의도적 인 null 인 선택적 매개 변수가있는 경우입니다.


여기에 언급 된 몇 가지 옵션을 시도하고 성능을 테스트했습니다. 이 순간 논리자가 가장 빠른 것 같습니다. 시간이 지남에 따라 변경 될 수 있지만 (다른 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>

이것이 내가 끝낸 것입니다.

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" });

여러분-

이러한 솔루션과 다른 솔루션을 살펴본 후 W3Schools의 원래 코드 스 니펫을 기반으로 여러 가지를 시도했습니다. 다음에서 작동하는 것을 찾을 수 있습니다. 주석 처리 된 각 항목도 작동하며 개별 주석을 제거하는 것만으로 실험 할 수 있습니다. 명확하게 말하면 정의되지 않은 것은 "eyecolor"매개 변수입니다.

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."; 

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/


여기 내 해결책이 있습니다. 이를 통해 원하는 매개 변수를 남길 수 있습니다. 선택적 매개 변수의 순서는 중요하지 않으며 사용자 정의 유효성 검증을 추가 할 수 있습니다.

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'
        });

  1. arg || 'default' 90 %의 경우에 효과적이며

  2. '거짓'일 수있는 값을 전달해야 할 때 실패합니다.

    • false
    • 0
    • NaN
    • ""

    이러한 경우에는 좀 더 자세한 내용을 확인하고 undefined

  3. 또한 먼저 선택적 인수가있을 때주의해야합니다. 모든 인수의 유형을 알고 있어야합니다.


optionalArg가 거짓 인 모든 경우에 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);

6 개 모두 거짓이므로 위의 모든 로그 defaultValue. 4, 5, 6의 경우 optionalArg를 defaultValue로 설정하는 데 관심이 없을 수도 있지만 거짓이므로 설정됩니다.


내가 틀렸다면 정정하십시오.하지만 이것은 가장 간단한 방법처럼 보입니다 (어쨌든 한 가지 주장에 대해).

function myFunction(Required,Optional)
{
    if (arguments.length<2) Optional = "Default";
    //Your code
}

그것들은 typeof 연산자 버전보다 짧습니다.

function foo(a, b) {
    a !== undefined || (a = 'defaultA');
    if(b === undefined) b = 'defaultB';
    ...
}

다음과 같이 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

}

기본값 을 사용하기로 결정하기 전에 제공된 모든 잘못된 유형인수\ 처리하는 가장 안전한 방법 은 호출 된 함수에서 선택적 인수 의 존재 여부를 확인하는 것 입니다.

인수가 선언 될 수 있다는 사실에 관계없이 인수가 누락 되어도 생성되지 않는 인수 개체 멤버 생성에 의존하여 다음과 같이 함수를 작성할 수 있습니다.

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

이 동작 활용 : 함수가 프로 시저에 필요한 특정 값을 가져 오는지 확인해야 할 때마다 인수 목록에서 누락 된 값을 임의로 명시 적으로 확인할 수 있습니다.

다음 데모 코드에서 우리는 의도적으로 넣어 것입니다 관대 하고 무가치 정의되지 않은 예상대로 동작하는 경우 등과 같은 거짓, 그것은 falsy 인수 값에 실패 할 수 있습니다 여부를 판단 할 수있는 기본 값을, 또는.

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

즉, 예상되는 인수 값의 인식에 실패하지 않았습니다. 여기에 모든 인수가 누락 된 확인이 있습니다. 알고리즘에 따라 falsy 하더라도 기본값을 획득해야합니다 .

argCheck( );
>> undefined false 0 null

보시다시피 arg1, arg2, arg3 및 선언되지 않은 arg4 인수 는 순서대로 정확한 기본값을 반환합니다 . 이제 작동하는지 확인 했으므로 if 또는 삼항 조건 을 사용하여 첫 번째 예제에서와 같이 실제로 사용할 수있는 함수를 다시 작성할 수 있습니다.

하나 이상의 선택적 인수가있는 함수에서-루프 스루는 우리에게 약간의 비트를 절약 할 수 있습니다. 그러나 인수 이름 은 값이 제공되지 않으면 초기화되지 않으므로 프로그래밍 방식으로 기본값을 작성 했더라도 더 이상 이름으로 액세스 할 수 없습니다 . 코드 가독성 측면에서 쓸모없는 arguments [index] 로만 액세스 할 수 있습니다 .

그러나 특정 코딩 상황에서 완전히 수용 할 수있는 이러한 불편 함을 제외하고, 여러 임의의 인수 기본값에 대한 설명되지 않은 또 다른 문제가 있습니다. 다음과 같은 구문에서 값을 제공하지 않고 할 수 있었던 것처럼 더 이상 인수를 건너 뛸 수 없기 때문에 버그로 간주 될 수 있고 고려해야합니다.

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

던질 것이기 때문에! 이것은 우리가 원하는 기본값의 특정한 거짓 유형으로 우리 의 주장을 대체하는 것을 불가능하게합니다 . 인수 객체 는 배열과 같은 객체이고 기본적으로 또는 기본적으로이 구문과 규칙을 그대로 지원할 것으로 예상 되기 때문에 어리석은 일입니다 !

이 근시안적인 결정 때문에 우리는 더 이상 다음과 같은 함수를 작성하기를 바랄 수 없습니다.

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 );
}

추신 : 내 인수 입력에서 선택한 기본값 유형 을 작성하는 동안 유지하지 않아서 죄송 합니다.


function foo(requiredArg){
  if(arguments.length>1) var optionalArg = arguments[1];
}

참고 URL : https://stackoverflow.com/questions/148901/is-there-a-better-way-to-do-optional-function-parameters-in-javascript

반응형