Javascript에서 동적으로 이름이 지정된 메서드를 어떻게 호출합니까?


113

웹 페이지가 구성 될 때 삽입 될 일부 JavaScript를 동적으로 만드는 작업 중입니다.

JavaScript는 listbox다른 listbox. 하나의 선택 listbox이 변경되면 선택한 값에 따라 메서드 이름이 호출됩니다 listbox.

예를 들면 :

Listbox1 포함 :

  • Colours
  • Shapes

Colours를 선택 하면 populate_Colours다른을 채우는 메서드를 호출합니다 listbox.

내 질문을 명확히하기 위해 : populate_ColoursJavaScript에서 어떻게 호출합니까?


단일 '채우기'방법으로 지역 지점을 갖는 것에 찬성하여 이에 반대하는 것이 좋습니다. 그것은 더 검증하고 더 적은 "해키"볼 것
아론 파월에게

여기 내 대답을 참조하십시오. 자바 스크립트에서 이름으로 전화
Hugo R

답변:


208

populate_Colours메서드가 전역 네임 스페이스에 있다고 가정하면 모든 개체 속성에 개체가 연관 배열 인 것처럼 액세스 할 수 있고 모든 전역 개체가 실제로 window호스트 개체의 속성임을 모두 이용하는 다음 코드를 사용할 수 있습니다 .

var method_name = "Colours";
var method_prefix = "populate_";

// Call function:
window[method_prefix + method_name](arg1, arg2);

9
응답 해 주셔서 감사합니다. '창'비트는 내가 그것을 검색하고 전역 개체가 창 개체의 일부라는 것을 알 때까지 실제로 나를 던졌습니다. 이제 말이됩니다! 감사합니다. 참고로 여기에서 좋은 페이지를 찾았습니다 devlicio.us/blogs/sergio_pereira/archive/2009/02/09/…
Chris B

3
내가 목표로 삼은 함수가 jQuery "fn"네임 스페이스에 있다는 점을 제외하면 비슷한 작업을 수행했습니다. 예 :$.fn[method_prefix + method_name](arg1, arg2);
codecraig 2011 년

1
좋은. 아마도 try/ catch블록을 추가 할 가치가 있습니다.
LeeGee 2014-09-20

이것은 일부에 분명하지만, 일에 그것을 얻을 수없는 사람들을 위해 할 수 있습니다 : 당신의 외부 기능을 던져 $(function () {window.load코드 :
스탠 스멀 더스

1
@peter 대괄호는이 컨텍스트에서 속성 접근자가 아니기 때문에 배열을 나타냅니다. 배열은 함수가 아니므로 호출 할 수 없습니다.
user4642212

39

Triptych가 지적했듯이 호스트 개체의 내용에서 모든 전역 범위 함수를 찾아 호출 할 수 있습니다.

전역 네임 스페이스를 훨씬 덜 오염시키는 더 깨끗한 방법은 다음과 같이 함수를 배열에 직접 명시 적으로 넣는 것입니다.

var dyn_functions = [];
dyn_functions['populate_Colours'] = function (arg1, arg2) { 
                // function body
           };
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
                // function body
           };
// calling one of the functions
var result = dyn_functions['populate_Shapes'](1, 2);
// this works as well due to the similarity between arrays and objects
var result2 = dyn_functions.populate_Shapes(1, 2);

이 배열은 전역 호스트 객체가 아닌 다른 객체의 속성 일 수도 있습니다. 즉, jQuery와 같은 많은 JS 라이브러리가 수행하는 것처럼 자신 만의 네임 스페이스를 효과적으로 만들 수 있습니다. 이것은 동일한 페이지에 여러 개의 개별 유틸리티 라이브러리를 포함 할 때 충돌을 줄이는 데 유용하며 (디자인의 다른 부분이 허용하는 경우) 다른 페이지에서 코드를 더 쉽게 재사용 할 수 있습니다.

다음과 같은 객체를 사용할 수도 있습니다.

var dyn_functions = {};
dyn_functions.populate_Colours = function (arg1, arg2) { 
                // function body
           };
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
                // function body
           };
// calling one of the functions
var result = dyn_functions.populate_Shapes(1, 2);
// this works as well due to the similarity between arrays and objects
var result2 = dyn_functions['populate_Shapes'](1, 2);

배열이나 객체를 사용하여 함수를 설정하거나 액세스하는 방법을 사용할 수 있으며 물론 다른 객체도 거기에 저장할 수 있습니다. 다음과 같이 JS 리터럴 표기법을 사용하여 동적이지 않은 콘텐츠에 대한 두 메서드의 구문을 더 줄일 수 있습니다.

var dyn_functions = {
           populate_Colours:function (arg1, arg2) { 
                // function body
           };
         , populate_Shapes:function (arg1, arg2) { 
                // function body
           };
};

편집 : 물론 더 큰 기능 블록의 경우 코드 기능을 체계적으로 캡슐화하는 인기있는 방법 인 매우 일반적인 "모듈 패턴"으로 위를 확장 할 수 있습니다.


그것은 깨끗하게 유지하는 좋은 방법입니다. 그래도 메서드를 어떻게 호출할까요? window [dyn_functions [ 'populate_Colours'] (arg1, arg2)가 작동합니까?
Chris B

내 질문에 답하기-방금 window [dyn_functions [ 'populate_Colours'] (arg1, arg2)]를 테스트했습니다. 그리고 그것은 실제로 작동합니다.
Chris B

4
epascarello가 지적했듯이 일반적으로 "window"- "dyn_functions [ 'populate_Colours'] (arg1, arg2);"가 필요하지 않습니다. 작동합니다. 사실 전역 객체의 이름을 포함하지 않으면 웹 브라우저가 아닌 JS 환경에서 사용될 수있는 루틴을 작성하는 경우 코드의 이식성이 향상됩니다. 하지만 예외가 있습니다. 함수에 dyn_functions라는 지역 변수가있는 경우 참조하는 항목을 더 구체적으로 지정해야하지만이 상황은 (분명한 명명 규칙을 사용하여) 피하는 것이 가장 좋습니다.
David Spillett

1
이 게시물은 '09 년에 작성되었으므로 지금 쯤이면 알겠지만 배열을 만들고 배열의 속성 (인덱스가 아님)에 할당합니다. 당신은 잘 할 수있는 var dyn_functions = {};당신이 불필요하게 배열을 생성하지 않도록이 비록 큰 문제가되지 않습니다 ....
David Sherret 2013

지나치게 복잡한 대답이지만 작동합니다. 일련의 패턴 화 된 기능이 있고 실행을 선택하기 위해 의사 결정 트리가 필요한 시나리오의 리소스로드가 생각됩니다.이 방법은 작업을 수행하는 데 지나치게 복잡 할 수 있습니다. 비록 내가 자신의 클래스 객체를 연결한다면 이것은 객체 자체를 정의하는 데 선호되는 접근 방식이 될 것입니다.
GoldBishop 2017

30

이 목적으로 / / 를 사용 하지 않는 것이 좋습니다 . 대신 다음과 같이하십시오. globalwindoweval

모든 메서드를 Handler의 속성으로 정의합니다.

var Handler={};

Handler.application_run = function (name) {
console.log(name)
}

이제 이렇게 불러

var somefunc = "application_run";
Handler[somefunc]('jerry');

출력 : jerry


17

다음과 같이 할 수 있습니다.

function MyClass() {
    this.abc = function() {
        alert("abc");
    }
}

var myObject = new MyClass();
myObject["abc"]();

5

내에서 ServiceWorker또는 Worker대체 window와 함께 self:

self[method_prefix + method_name](arg1, arg2);

작업자는 DOM에 액세스 할 수 없으므로 window잘못된 참조입니다. 이 용도에 해당하는 전역 범위 식별자는 self입니다.


2

다른 답변 중 일부가 제안하는 것처럼 창을 사용하지 않는 것이 좋습니다. this그에 따라 사용 하고 범위를 지정 하십시오 .

this['yourDynamicFcnName'](arguments);

또 다른 깔끔한 트릭은 다른 범위 내에서 호출하고 상속에 사용하는 것입니다. 함수를 중첩했고 전역 창 개체에 대한 액세스를 원한다고 가정 해 보겠습니다. 다음과 같이 할 수 있습니다.

this['yourDynamicFcnName'].call(window, arguments);

1

안녕하세요,

 var callback_function = new Function(functionName);
 callback_function();

매개 변수 자체를 처리합니다.


캐치되지 기준 오차 - FUNCTIONNAME 정의되지 않은
brianlmerritt의

@brianlmerritt에 대한 값을 정의해야합니다 functionName... 응답자는 이미 정의한 것으로 가정했습니다.
GoldBishop 2017

이러한 목적으로 new Function ()을 사용할 수 없습니다.
JCH77 '1912.22

-1

여기에서 작업하고 확인하기위한 간단한 해결책이 함수의 존재동적으로 차적으로 분류 기능을 다른 기능으로는;

트리거 기능

function runDynmicFunction(functionname){ 

    if (typeof window[functionname] == "function"  ) { //check availability

        window[functionname]("this is from the function it "); //run function and pass a parameter to it
    }
}

이제 다음과 같이 PHP를 사용하여 동적으로 함수를 생성 할 수 있습니다.

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

이제 동적으로 생성 된 이벤트를 사용하여 함수를 호출 할 수 있습니다.

<?php

$name_frm_somware ="runThis_func";

echo "<input type='button' value='Button' onclick='runDynmicFunction(\"".$name_frm_somware."\");'>";

?>

필요한 정확한 HTML 코드는

<input type="button" value="Button" onclick="runDynmicFunction('runThis_func');">

-3

이것을 시도하십시오 :

var fn_name = "Colours",
fn = eval("populate_"+fn_name);
fn(args1,argsN);

이 패턴 사용의 의미는 무엇입니까? 이 eval함수에는 사용과 관련된 이상한 부작용이 있다는 것을 읽었습니다 . 나는 그것이 최후의 수단이 아니라면 일반적으로 그것을 멀리하려고 노력합니다.
GoldBishop 2017
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.