JavaScript 함수 호출에서 인수를 어떻게 미리 설정할 수 있습니까? (부분 기능 적용)
나머지 모든 인수와 함께 해당 함수에 대한 사전 설정 매개 변수로 첫 번째 인수 (함수)를 반환하는 JavaScript 함수를 작성하려고합니다.
그래서:
function out (a, b) { document.write (a + ""+ b); } 함수 setter (...) {...} setter (out, "hello") ( "world"); setter (out, "hello", "world") ();
"hello world"를 두 번 출력합니다. setter의 일부 구현
첫 번째 시도에서 인수 배열을 조작하는 데 문제가 발생했지만이 작업을 수행하는 더 좋은 방법이있는 것 같습니다.
우선, 부분이 필요합니다 . 부분과 카레에는 차이가 있습니다. 여기 에 프레임 워크없이 필요한 모든 것이 있습니다 .
function partial(func /*, 0..n args */) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
var allArguments = args.concat(Array.prototype.slice.call(arguments));
return func.apply(this, allArguments);
};
}
이제 예제를 사용하여 정확히 원하는 작업을 수행 할 수 있습니다.
partial(out, "hello")("world");
partial(out, "hello", "world")();
// and here is my own extended example
var sayHelloTo = partial(out, "Hello");
sayHelloTo("World");
sayHelloTo("Alex");
이 partial()
함수는 구현에 사용할 수 있지만 커링 은 아닙니다 . 다음은 차이점에 대한 블로그 게시물 의 인용문입니다 .
부분 응용 프로그램이 함수를 취하고 더 적은 인수를 취하는 함수를 빌드하는 경우, currying은 각각 단일 인수를 취하는 함수의 구성으로 여러 인수를 취하는 함수를 빌드합니다.
도움이되기를 바랍니다.
가 카레 자바 스크립트 당신이 찾고있는 무슨 일이?
Dojo를 사용하는 경우 원하는 작업을 거의 정확하게 수행하는 dojo.hitch ()를 호출하면됩니다. 거의 — 컨텍스트를 압축하는데도 사용할 수 있기 때문입니다. 그러나 귀하의 예가 먼저입니다.
dojo.hitch(out, "hello")("world");
dojo.hitch(out, "hello", "world")();
만큼 잘:
var A = {
sep: ", ",
out: function(a, b){ console.log(a + this.sep + b); }
};
// using functions in context
dojo.hitch(A, A.out, "hello")("world");
dojo.hitch(A, A.out, "hello", "world")();
// using names in context
dojo.hitch(A, "out", "hello")("world");
dojo.hitch(A, "out", "hello", "world")();
dojo.hitch ()는 Dojo Base의 일부이므로 dojo.js를 포함하자마자 거기에 있습니다.
또 다른 일반적인 기능은 dojox.lang.functional.curry 모듈에서 사용할 수 있습니다 ( Dojo를 사용하는 JavaScript의 Functional fun에 문서화되어 있습니다 .이 페이지에서 "curry"를 찾으십시오). 특히 curry () 및 partial ()을보고 싶을 수 있습니다.
curry ()는 인수를 누적하지만 (예제에서와 같이) 한 가지 차이점이 있습니다. arity가 충족되는 즉시 값을 반환하는 함수를 호출합니다. 예제 구현 :
df.curry(out)("hello")("world");
df.curry(out)("hello", "world");
마지막 줄에는 끝에 "()"가 없습니다. 자동으로 호출됩니다.
partial ()은 임의로 인수를 대체 할 수 있습니다.
df.partial(out, df.arg, "world")("hello");
Javascript의를 사용 apply()
하여function prototype
Function.prototype.pass = function() {
var args = arguments,
func = this;
return function() {
func.apply(this, args);
}
};
그런 다음 다음과 같이 부를 수 있습니다. out.pass('hello','world')
apply
두 번째 인수 / 매개 변수에 대한 배열을 사용합니다.
arguments
구조와 같은 배열의 모든 매개 변수를 포함하는 함수 내에서 사용할 수있는 속성입니다.
이를 수행하는 또 다른 일반적인 방법은 bind
loadedFunc = func.bind(this, v1, v2, v3);
그때
loadedFunc() === this.func(v1,v2,v3);
약간 못 생겼지 만이 정도면 충분합니다.
Function.prototype.bind()
이것을 위해 사용할 수 있습니다 . ES5 추가입니다.
함수의 컨텍스트 ( this
값) 를 설정하는 일반적인 사용 사례 외에도 부분 인수를 설정할 수도 있습니다.
function out(a, b) {
document.write(a + " " + b);
}
function setter(func) {
return func.bind.apply(func, [window].concat([].slice.call(arguments).slice(1)));
}
setter(out, "hello")("world");
setter(out, "hello", "world")();
내 setter
기능은 실제로 매우 간단합니다. 가장 긴 부분은 인수 목록을 가져 오는 것입니다. 다음과 같이 코드를 나눌 것입니다.
func.bind.apply(func, [window].concat([].slice.call(arguments).slice(1)))
func.bind.apply( ) // need to use apply to pass multiple arguments as an array to bind()
func, // apply needs a context to be run in
[window].concat( ) // pass an array of arguments to bind(), starting with window, to be the global context
[].slice.call(arguments).slice(1) // convert the arguments list to an array, and chop off the initial value
지원되는 브라우저는 Chrome 7+, Firefox 4+, IE9 +입니다. MDN (처음에 링크 됨)에는 폴리 필이 있습니다.
** 편집 : Jason Bunting의 응답을 참조하십시오. 이 답변은 실제로 일부 인수에 대한 사전 설정이있는 단일 아웃 호출이 아니라 수많은 아웃 호출을 연결하는 하위 수준의 방법을 보여줍니다. 이 답변이 실제로 유사한 문제에 도움이된다면, 제가 생각했던 eval을 사용하는 모호한 방법 대신 Jason이 권장하는대로 apply 및 call을 사용해야합니다. **
글쎄 ... 당신의 아웃은 실제로 이것에 "정의되지 않음"을 많이 쓰겠지만 ... 이것은 당신이 원하는 것에 가까워 야합니다 :
function out(a, b) {
document.write(a + " " + b);
}
function getArgString( args, start ) {
var argStr = "";
for( var i = start; i < args.length; i++ ) {
if( argStr != "" ) {
argStr = argStr + ", ";
}
argStr = argStr + "arguments[" + i + "]"
}
return argStr;
}
function setter(func) {
var argStr = getArgString( arguments, 1 );
eval( "func( " + argStr + ");" );
var newSettter = function() {
var argStr = getArgString( arguments, 0 );
if( argStr == "" ) {
argStr = "func";
} else {
argStr = "func, " + argStr;
}
return eval( "setter( " + argStr + ");" );
}
return newSettter;
}
setter(out, "hello")("world");
setter(out, "hello", "world")();
나는 아마도 getArgString의 코드를 setter 함수 자체로 옮길 것입니다 ... 'eval 's를 사용했기 때문에 조금 더 안전합니다.
'IT이야기' 카테고리의 다른 글
Jupyter 노트북에서 셀 출력을 지우는 바로 가기 키 (0) | 2021.03.21 |
---|---|
CMake는 Boost를 찾지만 가져온 대상은 Boost 버전에서 사용할 수 없을 때 (0) | 2021.03.21 |
최고의 Drupal 배포 전략 (0) | 2021.03.21 |
Javascript로 replaceAll 만들기 (0) | 2021.02.22 |
Javascript로 이메일주소 정합성 체크하기 (이메일주소 검증, 정규식) (0) | 2021.02.22 |