IT story

인수가 JavaScript 함수로 전송되지 않는지 확인하는 가장 좋은 방법

hot-time 2020. 4. 16. 08:28
반응형

인수가 JavaScript 함수로 전송되지 않는지 확인하는 가장 좋은 방법


이제 인수가 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);
}

Juan의 의견에 따라 Tom의 제안을 다음과 같이 변경하는 것이 좋습니다.

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

    alert(argument2);
}

인수가 함수에 전달되었는지 확인하는 방법에는 여러 가지가 있습니다. (원래) 질문에서 언급 한 두 가지 외에도 연산자를 확인 arguments.length하거나 사용하여 ||기본값을 제공하는 경우 undefinedvia 통해 argument2 === undefined또는 typeof argument2 === 'undefined'편집증이 있는지에 대한 인수를 명시 적으로 확인할 수 있습니다 (주석 참조).

은 Using ||조작하는 표준 관행이되었다 - 모든 차가운 아이가 그것을 할 -하지만 조심 : 기본 값은 인수 평가되는 경우에 트리거됩니다 false실제로 할 수있는 수단, undefined, null, false, 0, ''(또는 다른 것을하는 Boolean(...)반환 false).

따라서 어떤 검사를 언제 사용해야하는지에 대한 질문은 모두 약간 다른 결과를 낳습니다.

점검 arguments.length은 '가장 올바른'행동을 나타내지 만, 하나 이상의 선택적 인수가있는 경우에는 실행되지 않을 수 있습니다.

테스트 undefined는 다음에 '최고'입니다. 함수가 명시 적으로 undefined으로 호출 된 경우에만 '실패'합니다 . 인수를 생략하는 것과 같은 방식으로 처리해야합니다.

의 사용 ||운영자는 유효한 인수가 제공되는 경우에도 기본 값의 사용을 트리거 할 수 있습니다. 반면에, 실제로는 그 동작이 필요할 수 있습니다.

요약 : 당신이하고있는 일을 알고있는 경우에만 사용하십시오!

내 의견으로는, ||하나 이상의 선택적 인수가 있고 명명 된 매개 변수에 대한 해결 방법으로 객체 리터럴을 전달하지 않으려는 경우 사용하는 방법도 있습니다.

arguments.lengthswitch 문의 레이블을 통해 기본값을 사용하는 또 다른 좋은 방법 이 가능합니다.

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
}

이것은 프로그래머의 의도가 (시각적으로) 명확하지 않으며 '마법의 숫자'를 사용한다는 단점이 있습니다. 따라서 오류 가능성이 높습니다.


jQuery를 사용하는 경우 (특히 복잡한 상황에서) 좋은 옵션 중 하나는 jQuery의 extend 메소드 를 사용 하는 것 입니다.

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

이것은 테스트를 찾는 몇 가지 경우 중 하나입니다.

if(! argument2) {  

}

꽤 잘 작동하고 구문 적으로 올바른 의미를 전달합니다.

(동시 제한으로 argument2인해 다른 의미가 있는 합법적 인 null 값을 허용하지 않지만 실제로는 혼란 스럽습니다.)

편집하다:

이것은 느슨한 언어와 강력한 언어 사이의 문체 차이의 좋은 예입니다. 자바 스크립트가 스페이드로 제공하는 스타일 옵션.

저의 개인적 선호 (다른 선호를위한 비판이 없음)는 미니멀리즘입니다. 일관성 있고 간결한 코드의 말이 적을수록 다른 사람이 내 의미를 올바르게 유추 할 수있는 사람이 줄어 듭니다.

이 환경 설정의 한 가지 의미는 여러 가지 유형 의존성 테스트를 쌓고 싶지 않다는 것입니다. 대신, 코드가 의미하는 것처럼 보이도록 코드를 만들려고합니다. 실제로 테스트해야 할 항목 만 테스트하십시오.

다른 사람들의 코드에서 찾은 악화 중 하나는 더 큰 맥락에서 실제로 테스트중인 사례에 도달 할 것으로 기대하는지 여부를 파악해야합니다. 또는 그들이 가능한 모든 것을 테스트하려고 할 때, 문맥을 완전히 예상하지 못할 가능성이 있습니다. 즉, 자신감있게 리팩토링하거나 수정하기 전에 양방향으로 철저히 추적해야합니다. 나는 그들이 필요로하는 상황을 예측했기 때문에 (그리고 일반적으로 나에게는 분명하지 않은) 다양한 시험을 시행 할 가능성이 높다고 생각한다.

(이 사람들이 동적 언어를 사용하는 방식에 심각한 단점이 있다고 생각합니다. 너무 많은 사람들이 모든 정적 테스트를 포기하고 결국 가짜를 원하지 않습니다.)

포괄적 인 ActionScript 3 코드와 우아한 자바 스크립트 코드를 비교할 때 가장 눈에 띄게 나타났습니다. AS3은 js의 3 배 또는 4 배가 될 수 있으며, 결정된 코딩 결정의 수 (3-4X) 때문에 신뢰성이 적어도 나쁘지 않다고 생각합니다.

당신이 말했듯이, Shog9, YMMV. :디


중요한 차이점이 있습니다. 몇 가지 테스트 사례를 설정해 보겠습니다.

var unused; // value will be undefined
Test("test1", "some value");
Test("test2");
Test("test3", unused);
Test("test4", null);
Test("test5", 0);
Test("test6", "");

첫 번째 방법에서는 두 번째 테스트 만 기본값을 사용합니다. 두 번째 방법은 JS 변환되므로 (첫번째 제외한 모든 기본 것 undefined, null, 0, 및 ""부울로 false는 톰의 방법을 사용한다면. 그리고, 4 번째 테스트가 기본값을 사용합니다!

어떤 방법을 선택하는지는 의도 한 행동에 따라 다릅니다. undefined에 허용되는 값 이외의 값이 있으면 argument2첫 번째 변형을 원할 것입니다. 0이 아닌 null이 아닌 비어 있지 않은 값이 필요한 경우 두 번째 방법이 이상적입니다. 실제로 이러한 넓은 범위의 값을 고려에서 신속하게 제거하는 데 종종 사용됩니다.


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

죄송합니다. 아직 댓글을 달 수 없으므로 Tom의 답변에 답변을 드리겠습니다 ... javascript (undefined! = null) == false 해당 함수가 "null"과 함께 작동하지 않으면 "undefined"를 사용해야합니다.


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

선택적 속성의 Object로 함수를 호출하여 인수 감지에 접근하는 것이 편리 할 수 ​​있습니다.

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

잘 찾을 수있는 등 까다로운 방법은 매개 변수가 함수 나하지로 전달되는지 여부 . 아래 예를 살펴보십시오.

this.setCurrent = function(value) {
  this.current = value || 0;
};

이것은 필요한 값이 value존재하지 않거나 통과하면 0으로 설정 한다는 것을 의미합니다 .

꽤 멋지다!


때로는 getter 및 setter로 함수를 사용하는 경우 유형을 확인하고 싶을 수도 있습니다. 다음 코드는 ES6입니다 (EcmaScript 5 이상에서는 실행되지 않음).

class PrivateTest {
    constructor(aNumber) {
        let _aNumber = aNumber;

        //Privileged setter/getter with access to private _number:
        this.aNumber = function(value) {
            if (value !== undefined && (typeof value === typeof _aNumber)) {
                _aNumber = value;
            }
            else {
                return _aNumber;
            }
        }
    }
}

fnCalledFunction (Param1, Param2, window.YourOptionalParameter)

위의 함수가 많은 곳에서 호출되고 모든 곳에서 처음 두 개의 매개 변수가 전달되었지만 세 번째 매개 변수는 확실하지 않은 경우 window를 사용할 수 있습니다.

window.param3은 호출자 메소드에서 정의되지 않은 경우 처리합니다.

참고 : https://stackoverflow.com/questions/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function

반응형