JavaScript 함수가 정의되어 있는지 확인하는 방법


302

JavaScript의 함수가 정의되어 있는지 어떻게 알 수 있습니까?

나는 이런 식으로하고 싶다

function something_cool(text, callback) {
    alert(text);
    if( callback != null ) callback();
}

그러나 그것은 나를 얻는다

콜백은 함수가 아닙니다

콜백이 정의되지 않은 경우 오류가 발생합니다.

답변:


475
typeof callback === "function"

47
typeof 값 집합이 ECMA 사양에 정확하게 정의되어 있기 때문에 이것은 실제로 마법의 문자열이 아닙니다. 이것에 대한 구문은 시작하기에 약간 어색하지만 완벽하게 합리적인 관용적 자바 스크립트입니다.
Ben Zotto

2
@quixoto-이해, 나는 당신이 여전히 관계없이 문자열을 가져야한다는 것을 의미한다고 생각합니다. 나는 절대적으로 필요한 것보다 내 코드를 어지럽히는 리터럴 문자열이 더 이상 없을 것입니다. 따라서 이것이 함수인지 테스트하는 데 이상적이지 않습니다.
Jason Bunting

4
그렇습니다. "매직"은 엉성하고 잘못된 단어 선택이었습니다. "매직 문자열"이 아닌 "문자열"을 의미했습니다. 내 잘못이야. :)
Jason Bunting


함수에서 괄호를 제거하고 if 조건에서 함수 이름 만 사용하십시오. 그렇지 않으면 함수가 true 또는 false를 제공하는 대신 호출됩니다.
Russell Strauss

236

현재의 모든 답변은 리터럴 문자열을 사용합니다. 가능한 경우 코드에없는 것을 선호합니다.

function isFunction(possibleFunction) {
  return typeof(possibleFunction) === typeof(Function);
}

개인적으로 코드에 걸려있는 문자열 수를 줄이려고합니다 ...


또한 typeof함수가 아니라 연산자 라는 것을 알고 있지만 구문을 사용하면 후자로 표시되는 데 거의 해가 없습니다.


7
이 기능을 어떻게 사용해야합니까? 나는 해봤 isFunction(not_defined))not_defined정의되지 않은 함수의 이름이고 불을 지르고 반환 not_defined is not defined정확하다 ...하지만 기능은 오류가 발생 false를 반환하지해야하는
Wookie88

@ Wookie88 : 기술적으로 말하면 JavaScript 응답이 not_defined값을 전달하기 위해 기호를 해석하려고 시도하고 해석하지 못하기 때문에 내 대답에 표시된 함수는 오류가 발생하는 것처럼 오류를 반환하지 않습니다 isFunction(). isFunction()이 문제를 해결하기 위해 정의를 수행 할 수있는 것은 없습니다 .
Jason Bunting

3
@ZacharyYates ReferenceError를 해결하는 방법은 정의되지 않은 함수에 대한 참조로 작업하지 않는 것을 의미합니다. 함수 호출 내에서 유형 검사를 수행하고 결과를 함수에 전달할 수 있습니다. jsfiddle.net/qNaxJ 어쩌면 그렇게 좋지는 않지만 적어도 문자열을 사용하지는 않았다;)
netiul

8
또는 기능을 피하고 isFunction그냥하십시오 (typeof no_function == typeof Function).
netiul

2
@JasonBunting 그 까다로운 일이 되려면 typeof(Function())Function이 함수이기 때문에 실제로 사용해야합니다 . 그러나 더 나은 용어가없는 배열, 객체 및 기타 내장 프로토 타입도 마찬가지입니다. 배열을 확인하는 typeof(array) === typeof(Array)경우 예를 들어 사용하지 않을 것 입니다. typeof(array) === typeof(Array())신중하고 일관성이 있다면 실제로 함수를 평가해야하기 때문에 사용 합니다.
seanmhanson

16
if (callback && typeof(callback) == "function")

가 평가 (자체)이 콜백주의 false가있는 경우 undefined, null, 0, 또는 false. 과 비교하면 null지나치게 구체적입니다.


2
또한 callback자체가 "false-y"값으로 평가 되면 해당 typeof는 "기능"이 될 수 없습니다 .
Joe

5
@Joe, 그러나 단락으로 인해 콜백이 false로 평가되면 해당 테스트가 수행되지 않습니다.
Fabio A.

3
첫 번째 조건은 즉시 예외를 발생시키기 때문에이 솔루션은 작동하지 않습니다. 이것은 객체의 속성에 대해 작동 할 수 있습니다. if (obj.callback) {...}
Roey

8

변수가 정의되어 있지 않으면 함수가 구현되었는지 알려주는 메소드도 실패하므로 문자열 수신을 지원하는 더 강력한 것을 사용하고 있습니다.

function isFunctionDefined(functionName) {
    if(eval("typeof(" + functionName + ") == typeof(Function)")) {
        return true;
    }
}

if (isFunctionDefined('myFunction')) {
    myFunction(foo);
}

좋은 대답이라고 생각합니다. 맞습니다. 위의 모든 방법이 실패하면 함수가 정의되지 않은 것입니다.
Matteo Conta

정의되지 않은 참조를 피하는 것은 쉽지 않습니다 . typeof window.doesthisexist대신 간단히 참조하십시오 doesthisexist. 그러나 표시된대로 eval (악 :)을 사용하면 명명 된 함수에서만 작동합니다. 문제의 유스 케이스에서는 작동하지 않습니다.
AD7six

이것은 전역 범위에서만 작동하며 허용되는 답변은 로컬 범위 기능에서도 작동한다는 점에 유의하십시오.
inf3rno

6

JavaScript를 처음 접했을 때 동작이 변경되었는지 확실하지 않지만 가능한 경우 기능이 정의되어 있지 않으면 Jason Bunting (6 년 전)이 제공 한 솔루션이 작동하지 않습니다.

function isFunction(possibleFunction) {
  return (typeof(possibleFunction) == typeof(Function));
}

ReferenceError: possibleFunction is not defined엔진이 possibleFunction 기호를 해결하려고 시도 하면 오류가 발생합니다 (Jason의 답변에 대한 주석에서 언급 한 바와 같이)

이 동작을 피하려면 검사하려는 기능의 이름 만 전달하면됩니다. 그래서

var possibleFunction = possibleFunction || {};
if (!isFunction(possibleFunction)) return false;

변수를 확인하려는 함수 또는 정의되지 않은 경우 빈 개체로 설정하므로 위에서 언급 한 문제를 피할 수 있습니다.


완전히 명확하게하기 위해 : 내 코드는 오류를 발생시키지 않습니다 .JavaScript 파서 일뿐입니다. 이러한 방식으로 정의되지 않은 식별자를 사용하려고 시도한 경우에도 마찬가지입니다.
Jason Bunting

6

시험:

if (typeof(callback) == 'function')

HI, "느슨한"비교 (==)를 사용하지 마십시오. 항상 변수의 유형까지도 비교하려면 '==='을 사용하십시오.
Joel Carneiro

4
function something_cool(text, callback){
    alert(text);
    if(typeof(callback)=='function'){ 
        callback(); 
    };
}

4
if ('function' === typeof callback) ...

3
비트 현학적는 여전히 문자열 리터럴을 사용합니다. 어때요 if(typeof Function === typeof callback)...? :)
Jason Bunting

@JasonBunting 궁금합니다. 문자열 리터럴을 사용하는 데 무엇이 문제입니까?
Bsienn

@Bsienn-내가 말했듯이, 그것은 나에게 놀랍지 만 여기에있는 것이 있습니다. 하자 당신은 문자열 리터럴과 코드 및 호출 사용하는 말 typeof은 - 때문에 자바 스크립트의 새 / 다른 구현으로, 나중에 반환 뭔가 다른 (대신 "기능"어쩌면 "기능") 느낌 이 덜하는 것처럼 새로운 / 다른 구현은 typeof Function === typeof callback의미 수준에서 동일해야하기 때문에 검사를 중단합니다 .
Jason Bunting


4

나는 할지도 모른다

try{
    callback();
}catch(e){};

나는 대답이 받아 들여진다는 것을 알고 있지만 아무도 이것을 제안하지 않았다. 이것이 관용구의 설명에 맞는지 확실하지 않지만 모든 경우에 작동합니다.

최신 JavaScript 엔진에서는 a finally를 대신 사용할 수 있습니다.


깔끔한 지름길입니다! 함수가 존재하거나 정의 된 경우 (테스트하지 않고) 테스트하는 경우에만 작동하지 않습니다.
Beejor

사실입니다. 해당 실행 지점에서 콜백이 선택적인 상황을 가정했습니다. 나는 보통 typeof callback어쨌든 사용 합니다.
Quentin Engles

말이 되네요. 내용보다 질문 제목에 더 집중했습니다. 때로는 try-catch를 사용하여 여러 가지 테스트를 수행하는 단순함을 좋아합니다. 이 경우에는 typeof와 비교하여 사용하는 데 기술적 인 단점이 있다고 생각하십니까? 아니면 주로보다 적절하고 예상 된 방식으로 일을하는 것입니까?
Beejor

1
여러 유형을 테스트하려면 예외가 그렇게 좋지 않습니다. 예를 들어, 현재 작업중 인 프로젝트는 하나의 변수에서 많은 유형 검사를 사용하여 함수, 문자열 또는 기타 무엇인지 확인합니다. 이 프로젝트에서는 실제로 유형이 필요합니다. 이를 위해 유형 배열을 사용하고 유형 accepted_types.indexOf(typeof value) !== -1범위에 있는지 확인 합니다. 이런 상황에서는 예외적으로 제 생각에는 예외가 될 것입니다.
Quentin Engles

2

이 시도:

callback instanceof Function

1
작동하지 않습니다. 여전히 오류가 발생합니다. 답변으로 게시하기 전에 직접 시도해야합니다.
vbullinger

@vbullinger 방금 Chrome, Firefox 및 Safari에서 다시 테스트했습니다. 모든 곳에서 작동합니다. 어떤 엔진으로 문제가 발생 했습니까?
eWolf

Firefox. 콜백이 정의되지 않은 경우를 테스트 했습니까?
vbullinger

이는 정의되지 않은 변수를 직접 참조하기 때문에 작동하지 않습니다. pastebin.com/UQz2AmzH
eWolf

3
저자가 요청한 함수 매개 변수에 사용될 때 작동합니다. ECMAScript가 존재하지 않는 변수와 기존 변수의 값을 undefined 값으로 구분한다고 가정합니다. 이것에 대해 더 알고 있으면 흥미로울 것입니다.
eWolf

2

@Venkat Sudheer Reddy Aedama 라이브러리 의 출처 를 보면 밑줄을 볼 수 있습니다.

_.isFunction = function(obj) {
  return typeof obj == 'function' || false;
};

이것은 단지 내 힌트, 힌트 답변입니다 :>




1

jQuery 함수가 정의되어 있는지 쉽게 확인하는 방법을 찾고있었습니다.

아마도 필요할 수도 있습니다.)

if(typeof jQuery.fn.datepicker !== "undefined")

동일 type0f($.datepicker) !== undefiled그렇지 않으면이 될 것입니다object
vladkras

0

경우 callback()이 함수에서 한 시간 동안하지 요구하고있다, 당신은 재사용을 위해 인수를 초기화 할 수 있습니다 :

callback = (typeof callback === "function") ? callback : function(){};

예를 들면 다음과 같습니다.

function something_cool(text, callback) {
    // Initialize arguments
    callback = (typeof callback === "function") ? callback : function(){};

    alert(text);

    if (text==='waitAnotherAJAX') {
        anotherAJAX(callback);
    } else {
        callback();
    }
}

제한은 정의되지 않았지만 항상 콜백 인수를 실행한다는 것입니다.


0

전역 함수 eval의 경우 답변 중 하나에서 제안하는 대신 이것을 사용할 수 있습니다 .

var global = (function (){
    return this;
})();

if (typeof(global.f) != "function")
    global.f = function f1_shim (){
        // commonly used by polyfill libs
    };

당신도 사용할 수 global.f instanceof Function있지만 afaik. 의 값은 Function프레임마다 다르므로 단일 프레임 응용 프로그램에서만 제대로 작동합니다. 우리가 보통 typeof대신 사용 하는 이유 입니다. 일부 환경에서는 예외가있을 수 있습니다 ( typeof f예 : MSIE 6-8). 예를 들어 일부 기능 alert에는 "개체"유형이 있습니다.

로컬 기능에 따라 허용 된 답변에서 해당 기능을 사용할 수 있습니다. 함수가 로컬인지 전역인지 테스트 할 수 있습니다.

if (typeof(f) == "function")
    if (global.f === f)
        console.log("f is a global function");
    else
        console.log("f is a local function");

질문에 대답하기 위해 예제 코드는 최신 브라우저에서 오류없이 작동하므로 문제가 무엇인지 잘 모르겠습니다.

function something_cool(text, callback) {
    alert(text);
    if( callback != null ) callback();
}

참고 : callback !== undefined대신에 사용 callback != null하지만 거의 동일합니다.


0

대부분의 이전 답변이 모두 함수를 호출하는 부작용이없는 경우

여기에 모범 사례

당신은 기능이 있습니다

function myFunction() {
        var x=1;
    }
그것을 테스트하는 직접적인 방법

//direct way
        if( (typeof window.myFunction)=='function')
            alert('myFunction is function')
        else
            alert('myFunction is not defined');
문자열을 사용하여 함수 이름을 정의 할 위치를 한 곳만 가질 수 있습니다

//byString
        var strFunctionName='myFunction'
        if( (typeof window[strFunctionName])=='function')
            alert(s+' is function');
        else
            alert(s+' is not defined');


0

함수를 재정의하려면 함수 발생 위치에 관계없이 함수가 전역 적으로 정의되므로 발생 순서에 따라 정의 된 함수 변수를 사용하는 것이 가장 좋습니다.

동일한 이름의 이전 함수를 호출하는 새 함수를 작성하는 예 :

A=function() {...} // first definition
...
if (typeof A==='function')
   oldA=A;
A=function() {...oldA()...} // new definition


-2

단선 솔루션 :

function something_cool(text, callback){
    callback && callback();
}

그의 예제는 함수가 정의 된 경우 함수가 호출되고, 그렇지 않은 경우 아무 일도 일어나지 않기를 원한다는 것을 보여줍니다. jsfiddle.net/nh1cxxg6 false / false 값을 반환하는 함수가 여전히 호출됩니다. 물론 값을 반환하려는 경우에는 작동하지 않습니다.
Samir Alajmovic

아, 나는 그의 질문을 잘못 읽었다. 그러나 콜백이 함수가 아닌 경우 예외가 발생합니다.
Frank Bryce
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.