본문으로 건너뛰기

기본 파라미터와 가변 파라미터_ES6 노트 4

무료2016-04-17#JS#ES6默认参数#ES6不定参数#JS可变参函数#JS设置默认参数

기본 파라미터와 가변 파라미터는 그동안 특정 기법을 통해 구현되어 왔는데, 이제야 '합법화'되었습니다

일. 역할

기본 파라미터와 가변 파라미터의 목표는 arguments 객체를 완전히 대체하는 것입니다

엄격 모드 ('use strict';) 는 arguments 에 다음과 같은 제한을 두었습니다:

  • eval 과 arguments 는 프로그램 구문을 통해 바인딩되거나 할당될 수 없습니다

  • 파라미터의 값은 arguments 객체의 값 변경에 따라 변하지 않으며, 그 반대도 마찬가지입니다

  • arguments.callee 지원이 중단되었습니다

(엄격 모드 - JavaScript | MDN 에서 인용)

처음 두 조항은 arguments 객체에 대한 불만이지만, arguments 객체는 가변 인수 함수를 구현하는 핵심 방법이기 때문에 (물론 Object/Array 타입 파라미터로 시뮬레이션할 수도 있지만 arguments 만큼 편리하고 유연하지는 않습니다), 계속 지원해야 하므로 엄격 모드 (패치) 를 통해 arguments 객체를 제한하려고 합니다

세 번째 조항은 흑기술이 봉인되었음을 나타내며, arguments 는 이름과 실상이 일치하게 되었습니다 (파라미터와만打交道)

ES6(새 버전) 는 엄격 모드를 기반으로 한 걸음 더 나아가, arguments 객체를 점차 잊어버리기를 바랍니다. 가변 파라미터가 대체 방안이며, 여기에锦上添花하는 기본 파라미터도 있습니다

이. 가변 파라미터

...arg 문법이 더 나은 의미 (가변 파라미터를 나타냄) 를 가져왔습니다

가변 파라미터는 가변 인수 함수 (임의의 개수 파라미터를 받아들일 수 있는 함수) 의 또 다른 구현 방식을 제공합니다 (arguments 객체 불필요). 특징은 다음과 같습니다:

  • 가독성이 더 좋아져 파라미터 목록에서 해당 함수가 가변 인수 함수임을 알 수 있으며, 파라미터 인덱스 (arguments[0]) 문제도 해결했습니다

  • 가변 파라미터는 파라미터 목록 끝에 있어야 하며, 추가 파라미터가 없을 때 값은 [] 이지 undefined 가 아닙니다

예:

function containsAny(s, ...aSubStr) {
    for (var subStr of aSubStr) {
        if (s.indexOf(subStr) !== -1) {
            return true;
        }
    }

    return false;
}
// test
console.log(containsAny('ECMAScript 6', 'es'));         // false
console.log(containsAny('ECMAScript 6', 'es', '6'));    // true

가변 파라미터가 가져온 편의는 파라미터 조작이 더 쉬워져 다음과 같은 단계가 불필요해졌습니다:

var fn = function(a, b) {
    var args = Array.prototype.slice.call(arguments);
    // 명명 파라미터 a 와 b 잘라내기
    var others = args.slice(2);
    // ...
}

삼. 기본 파라미터

arg=defaultVal 문법은 기본 파라미터를 나타내며, 다른 언어와 동일합니다. 특징은 다음과 같습니다:

  • defaultVal 은 임의의 합법적인 식이 될 수 있으므로, 왼쪽 파라미터를 기반으로 현재 파라미터의 기본값을생성할 수 있습니다

  • undefined 를 전달하는 것은플레이스홀더에 해당하며, 전달된 undefined 가 아니라 여전히 기본값을 사용합니다

  • 표준에서는 가변 파라미터 또는 기본 파라미터를 사용하는 함수 내에서arguments 객체 사용을 금지하고 있지만, Chrome49, FF45, thinkjs 는 이 제한을 구현하지 않았습니다

예:

function error(type = 'Undefined') {
    console.log(`${type} error occurs`);
}
// test
error();            // Undefined error occurs
error('Script');    // Script error occurs

// 동적으로 기본값 생성 및 undefined 전달
function hoho(name, sex, words = sex === 'F' ? 'Hi Girl' : 'Hello boy') {
    console.log(`${words}, you are ${name}`);
}
hoho('Sam', 'M');   // Hello boy, you are Sam
hoho('Lis', 'F');   // Hi Girl, you are Lis
hoho('Mee', 'F', undefined);    // Hi Girl, you are Mee

// arguments 객체
function fun(arg = 'defaultVal', ...aOther) {
    var args = Array.prototype.slice.call(arguments);
    console.log(args.length);
}
fun(1, 2, 3);   // 3

锦上添花한 작은 기능으로, 이전에는 주석을 통한 번거로운 작성 방식을 피할 필요가 있었습니다:

/**
 * [fn description]
 * @param  {[type]}   a [description]
 * @param  {[type]}   b 선택 가능, 기본값은 {}, xxx 를 나타냄
 * @return {Function}   [description]
 */
var fn = function(a, b) {
    b = b || {};    // b 의 기본값을 {}로 설정
}

이런 오래된 방법은 번거롭고 실수도 쉽게 발생하며 (b 가 0 이나 false 가 될 수 있을 때 더 번거로움), 기본 파라미터가 있으면 불필요한 주석이 필요 없습니다. 단, 기본값 생성 방식이 복잡한 경우 주석을 통해 추가 설명이 필요합니다

사. 요약

본 편의 내용은 매우 적으며, 주로 코드 가독성 향상에 관한 것으로, 2 가지 점이 있습니다:

  • 기본 파라미터 설정이 더 편리해졌으며, 문법이 기본 문법이 되었습니다

  • 가변 인수 함수가 더 합리적인 구현 방법을 얻어, arguments 객체에 의존하지 않게 되었습니다

참고 자료

  • 《ES6 in Depth》: InfoQ 中文站에서 제공하는 무료 전자책

댓글

아직 댓글이 없습니다

댓글 작성