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.