Javascript에서 인수 오버로딩에는 여러 측면이 있습니다.
가변 인수 -다른 인수 세트 (유형 및 수량 모두)를 전달할 수 있으며 함수는 전달 된 인수와 일치하는 방식으로 작동합니다.
기본 인수 -전달되지 않은 경우 인수의 기본값을 정의 할 수 있습니다.
명명 된 인수 -인수 순서는 관련이 없으며 함수에 전달할 인수의 이름 만 지정하면됩니다.
다음은 이러한 각 인수 처리 범주에 대한 섹션입니다.
가변 인수
자바 스크립트에는 인수에 대한 유형 검사가 없거나 인수의 수량이 필요 myFunc()하기 때문에 인수의 유형, 존재 또는 수량을 확인하여 전달 된 인수에 적응할 수있는 구현을 하나만 가질 수 있습니다.
jQuery는 항상이 작업을 수행합니다. 인수 중 일부를 선택적으로 만들거나 전달되는 인수에 따라 함수에서 분기 할 수 있습니다.
이러한 유형의 오버로드를 구현할 때 사용할 수있는 몇 가지 다른 기술이 있습니다.
- 선언 된 인수 이름 값이인지 확인하여 주어진 인수의 존재를 확인할 수 있습니다
undefined.
- 을 사용하여 총 수량 또는 인수를 확인할 수 있습니다
arguments.length.
- 주어진 인수의 유형을 확인할 수 있습니다.
- 가변 개수의 인수의 경우
arguments의사 배열을 사용하여 arguments[i].
여기 몇 가지 예가 있어요.
jQuery의 obj.data()방법을 살펴 보자 . 다음과 같은 네 가지 사용 형태를 지원합니다.
obj.data("key");
obj.data("key", value);
obj.data();
obj.data(object);
각각은 다른 동작을 트리거하며이 동적 형태의 오버로딩을 사용하지 않으면 4 개의 개별 함수가 필요합니다.
다음은 이러한 모든 옵션을 영어로 구분 한 다음 코드로 모두 결합하는 방법입니다.
// get the data element associated with a particular key value
obj.data("key");
전달 된 첫 번째 인수 .data()가 문자열이고 두 번째 인수가 undefined인 경우 호출자는이 양식을 사용해야합니다.
// set the value associated with a particular key
obj.data("key", value);
두 번째 인수가 정의되지 않은 경우 특정 키의 값을 설정하십시오.
// get all keys/values
obj.data();
인수가 전달되지 않으면 반환 된 객체의 모든 키 / 값을 반환합니다.
// set all keys/values from the passed in object
obj.data(object);
첫 번째 인수의 유형이 일반 객체 인 경우 해당 객체의 모든 키 / 값을 설정합니다.
이 모든 것을 하나의 자바 스크립트 로직 세트로 결합하는 방법은 다음과 같습니다.
// method declaration for .data()
data: function(key, value) {
if (arguments.length === 0) {
// .data()
// no args passed, return all keys/values in an object
} else if (typeof key === "string") {
// first arg is a string, look at type of second arg
if (typeof value !== "undefined") {
// .data("key", value)
// set the value for a particular key
} else {
// .data("key")
// retrieve a value for a key
}
} else if (typeof key === "object") {
// .data(object)
// set all key/value pairs from this object
} else {
// unsupported arguments passed
}
},
이 기술의 핵심은 수락하려는 모든 형식의 인수를 고유하게 식별 할 수 있고 호출자가 어떤 형식을 사용하고 있는지에 대해 혼동이 없도록하는 것입니다. 일반적으로 인수의 순서를 적절하게 지정하고 인수의 유형과 위치에 충분한 고유성이 있는지 확인하여 항상 어떤 형식이 사용되고 있는지 알 수 있어야합니다.
예를 들어, 세 개의 문자열 인수를받는 함수가있는 경우 :
obj.query("firstArg", "secondArg", "thirdArg");
세 번째 인수를 쉽게 선택적으로 만들 수 있으며 해당 조건을 쉽게 감지 할 수 있지만 두 번째 인수 만 선택적으로 만들 수는 없습니다. 인수는 두 번째 인수를 의미하거나 두 번째 인수가 생략되었으므로 두 번째 인수의 자리에있는 것은 실제로 세 번째 인수입니다.
obj.query("firstArg", "secondArg");
obj.query("firstArg", "thirdArg");
세 개의 인수가 모두 동일한 유형이므로 다른 인수의 차이를 알 수 없으므로 호출자가 의도 한 바를 알 수 없습니다. 이 호출 스타일에서는 세 번째 인수 만 선택 사항이 될 수 있습니다. 두 번째 인수를 생략하려면 null대신 (또는 다른 감지 가능한 값) 으로 전달 해야하며 코드에서 다음을 감지합니다.
obj.query("firstArg", null, "thirdArg");
다음은 선택적 인수의 jQuery 예제입니다. 두 인수 모두 선택 사항이며 전달되지 않으면 기본값을 사용합니다.
clone: function( dataAndEvents, deepDataAndEvents ) {
dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
return this.map( function () {
return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
});
},
다음은 인수가 누락 될 수있는 jQuery 예제 또는 네 가지 다른 오버로드를 제공하는 세 가지 유형 중 하나입니다.
html: function( value ) {
if ( value === undefined ) {
return this[0] && this[0].nodeType === 1 ?
this[0].innerHTML.replace(rinlinejQuery, "") :
null;
// See if we can take a shortcut and just use innerHTML
} else if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
value = value.replace(rxhtmlTag, "<$1></$2>");
try {
for ( var i = 0, l = this.length; i < l; i++ ) {
// Remove element nodes and prevent memory leaks
if ( this[i].nodeType === 1 ) {
jQuery.cleanData( this[i].getElementsByTagName("*") );
this[i].innerHTML = value;
}
}
// If using innerHTML throws an exception, use the fallback method
} catch(e) {
this.empty().append( value );
}
} else if ( jQuery.isFunction( value ) ) {
this.each(function(i){
var self = jQuery( this );
self.html( value.call(this, i, self.html()) );
});
} else {
this.empty().append( value );
}
return this;
},
명명 된 인수
Python과 같은 다른 언어에서는 일부 인수 만 전달하고 전달되는 순서와 관계없이 인수를 만드는 수단으로 명명 된 인수를 전달할 수 있습니다. Javascript는 명명 된 인수의 기능을 직접 지원하지 않습니다. 그 자리에서 일반적으로 사용되는 디자인 패턴은 속성 / 값의 맵을 전달하는 것입니다. 이것은 속성과 값이있는 객체를 전달하거나 ES6 이상에서 실제로 Map 객체 자체를 전달할 수 있습니다.
다음은 간단한 ES5 예입니다.
jQuery $.ajax()는 속성과 값이있는 일반 Javascript 객체 인 단일 매개 변수를 전달하는 사용 형태를 허용합니다. 전달하는 속성은 ajax 호출에 전달되는 인수 / 옵션을 결정합니다. 일부는 필수 일 수 있으며 많은 것은 선택 사항입니다. 객체의 속성이므로 특정 순서가 없습니다. 실제로 해당 객체에 전달할 수있는 30 개 이상의 서로 다른 속성이 있으며 하나 (URL) 만 필요합니다.
예를 들면 다음과 같습니다.
$.ajax({url: "http://www.example.com/somepath", data: myArgs, dataType: "json"}).then(function(result) {
// process result here
});
$.ajax()그런 다음 구현 내 에서 들어오는 객체에 전달 된 속성을 조사하여 명명 된 인수로 사용할 수 있습니다. 이는 for (prop in obj)모든 속성을 배열로 가져 오거나 배열 Object.keys(obj)을 반복 하여 수행 할 수 있습니다 .
이 기술은 많은 수의 인수가 있거나 많은 인수가 선택 사항 인 경우 Javascript에서 매우 일반적으로 사용됩니다. 참고 : 이는 최소한의 유효한 인수 집합이 있는지 확인하고 불충분 한 인수가 전달 된 경우 누락 된 부분을 호출자에게 디버그 피드백을 제공하기 위해 구현 함수에 부담을줍니다 (아마도 유용한 오류 메시지와 함께 예외를 던짐). .
ES6 환경에서는 위의 전달 된 객체에 대한 기본 속성 / 값을 생성하기 위해 구조 분해를 사용할 수 있습니다. 이에 대해서는 이 참조 문서 에서 자세히 설명 합니다.
다음은 해당 기사의 한 가지 예입니다.
function selectEntries({ start=0, end=-1, step=1 } = {}) {
···
};
이렇게하면 함수에 전달 된 객체 의 start, end및 step속성에 대한 기본 속성과 값이 생성 selectEntries()됩니다.
함수 인수의 기본값
ES6에서 Javascript는 인수의 기본값에 대한 기본 제공 언어 지원을 추가합니다.
예를 들면 :
function multiply(a, b = 1) {
return a*b;
}
multiply(5); // 5
이것이 MDN에서 사용되는 방법에 대한 자세한 설명입니다 .