IT이야기

JavaScript 함수 호출에서 인수 미리 설정하는 방법

cyworld 2021. 3. 21. 08:58
반응형

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를 사용했기 때문에 조금 더 안전합니다.

참조 URL : https://stackoverflow.com/questions/321113/how-can-i-pre-set-arguments-in-javascript-function-call-partial-function-appli

반응형