값이 함수인지 테스트


88

폼의 값이 onsubmit함수 인지 테스트해야 합니다. 형식은 일반적으로 onsubmit="return valid();". 이것이 함수인지, 호출 가능한지 알 수있는 방법이 있습니까? typeof를 사용하면 문자열이라는 것을 반환하므로별로 도움이되지 않습니다.

편집 : 물론, "유효한 반환 ();" 문자열입니다. 나는 replace그것을 "valid ();", 심지어 "valid ()"까지 내려왔다. 둘 중 하나가 함수인지 알고 싶습니다.

편집 : 내 문제를 설명하는 데 도움이 될 수있는 몇 가지 코드가 있습니다.

$("a.button").parents("form").submit(function() {
    var submit_function = $("a.button").parents("form").attr("onsubmit");
    if ( submit_function && typeof( submit_function.replace(/return /,"") ) == 'function' ) {
        return eval(submit_function.replace(/return /,""));
    } else {
        alert("onSubmit is not a function.\n\nIs the script included?"); return false;
    }
} );

편집 2 : 여기에 새 코드가 있습니다. form.submit () 호출은 기존 onsubmits를 실행하지 않기 때문에 여전히 eval을 사용해야하는 것 같습니다.

var formObj = $("a.button").parents("form");
formObj.submit(function() {
    if ( formObj[0].onsubmit && typeof( formObj.onsubmit ) == 'function' ) {
        return eval(formObj.attr("onsubmit").replace(/return /,""));
    } else {
        alert("onSubmit is not a function.\n\nIs the script included?");
        return false;
    }
} );

이 작업을 더 잘 수행하는 방법에 대한 제안?

답변:


85

제출 버튼을 앵커 링크로 바꾸고 있습니다. form.submit () 호출은 onsubmit을 활성화하지 않기 때문에 나는 그것을 찾고 eval () 직접 처리합니다. 하지만 거기에 무엇이 있는지 eval ()하기 전에 함수가 존재하는지 확인하고 싶습니다. – gms8994

<script type="text/javascript">
function onsubmitHandler() {
    alert('running onsubmit handler');
    return true;
}
function testOnsubmitAndSubmit(f) {
    if (typeof f.onsubmit === 'function') {
        // onsubmit is executable, test the return value
        if (f.onsubmit()) {
            // onsubmit returns true, submit the form
            f.submit();
        }
    }
}
</script>

<form name="theForm" onsubmit="return onsubmitHandler();">
<a href="#" onclick="
    testOnsubmitAndSubmit(document.forms['theForm']);
    return false;
"></a>
</form>

편집 : testOnsubmitAndSubmit 함수에서 매개 변수 f 누락

위의 내용은 onsubmitHTML 속성 을 지정하든 JavaScript에서 지정 하든 관계없이 작동합니다 .

document.forms['theForm'].onsubmit = onsubmitHandler;

1
f.onsubmit의 f는 어디에서 왔습니까?
— Art

f양식 인스턴스입니다. testOnsubmitAndSubmit 함수에 인수로 전달합니다. (이 질문은 꽤 오래 알고,하지만 어쩌면 내 대답은 사람에게 약간의 시간을 :) 저장됩니다)
— zeroos

63

시험

if (this.onsubmit instanceof Function) {
    // do stuff;
}

7
샘플 일뿐입니다. button.onsubmit instanceof Function
— artemb

13

간단히 typeof삼항 연산자와 함께 연산자 를 사용할 수 있습니다 .

onsubmit="return typeof valid =='function' ? valid() : true;"

함수라면 우리는 그것을 호출하고 반환 값을 반환하고 그렇지 않으면 그냥 반환합니다. true

편집하다:

나는 당신이 정말로 무엇을하고 싶은지 잘 모르겠지만, 무슨 일이 일어날 지 설명하려고 노력할 것입니다.

onsubmitHTML 내에서 코드 를 선언 하면 함수로 바뀌므로 JavaScript "world"에서 호출 할 수 있습니다. 이는이 두 가지 방법이 동일하다는 것을 의미합니다.

HTML: <form onsubmit="return valid();" />
JavaScript: myForm.onsubmit = function() { return valid(); };

이 두 가지는 모두 함수이고 둘 다 호출 가능합니다. typeof동일한 결과를 표시해야하는 연산자를 사용하여 테스트 할 수 있습니다 "function"..

이제 JavaScript를 통해 "onsubmit"속성에 문자열을 할당하면 문자열로 유지되므로 호출 할 수 없습니다. 이에 typeof대해 연산자 를 적용하면 "string"대신 "function".

나는 이것이 몇 가지를 명확히 할 수 있기를 바랍니다. 그런 다음 이러한 속성 (또는 문제에 대한 식별자)이 함수이고 호출 가능한지 알고 싶다면 typeof연산자가 트릭을 수행해야합니다. 여러 프레임에서 제대로 작동하는지 확실하지 않지만.

건배


그래도 onsubmit 외부에서 이것을 테스트해야합니다.
— Glen Solsberry

5

어떤 브라우저를 사용하고 있습니까?

alert(typeof document.getElementById('myform').onsubmit);

이것은 functionIE7 및 FireFox에서 " "를 제공합니다 .


onsubmit이 "return valid ();"인 경우에도?
— Glen Solsberry

1
예-잊지 마세요. 함수 외부에서 "반환"을 할 수 없습니다.
— Greg

form.onsubmit은 HTML 속성으로 정의 된 한 항상 함수입니다. 내 대답을 참조하십시오.
— Ionuț G. Stan

4

문자열 기반 변수를 예제로 사용하여 사용 instanceof Function 함수를 등록합니다. 변수 할당 ... 변수가 함수 이름인지 확인합니다 ... 사전 처리를 수행합니다 ... 함수를 새 변수에 할당합니다. 함수를 호출하십시오.

function callMe(){
   alert('You rang?');
}

var value = 'callMe';

if (window[value] instanceof Function) { 
    // do pre-process stuff
    // FYI the function has not actually been called yet
    console.log('callable function');
    //now call function
   var fn = window[value];
   fn();
}

2
fn 변수는 실제로 필요하지 않습니다. 그냥 window [value] ();
— Lajos Meszaros 2016 년

1
참으로 나는 알고 있지만 나는 또한 긴 형식으로 이해하기 쉽게는 일반적으로 실현이 어떠한 경우 @LajosMeszaros에 가치가 귀하의 의견을 배우기위한 사이트 주로
— CrandellWS

3

문자열 리터럴이 아닌 실제 함수에서 typeof를 호출하고 있는지 확인하십시오.

function x() { 
    console.log("hi"); 
}

typeof "x"; // returns "string"

typeof x; // returns "function"

3

필요에 맞게이 기술 을 수정할 수 있습니다 .

 function isFunction() {
   var functionName = window.prompt('Function name: ');
   var isDefined = eval('(typeof ' + functionName + '==\'function\');');
   if (isDefined)
     eval(functionName + '();');
   else
     alert('Function ' + functionName + ' does not exist');
 }
 function anotherFunction() {
   alert('message from another function.');
 }

2

form.onsubmit은 양식 요소의 HTML 속성으로 정의 될 때 항상 함수입니다. 이것은 HTML 요소에 연결된 일종의 익명 함수입니다. 이 포인터는 해당 FORM 요소에 바인딩 된 this 포인터 event가 있고 제출 이벤트에 대한 데이터를 포함하는 이름 이 지정된 매개 변수도 있습니다 .

이러한 상황에서는 작업 유형의 결과로 어떻게 문자열을 얻었는지 이해하지 못합니다. 더 자세한 정보와 더 나은 코드를 제공해야합니다.

편집 (두 번째 편집에 대한 응답으로) :

위의 코드에 관계없이 HTML 속성에 연결된 처리기가 실행될 것이라고 생각합니다. 더 나아가, 어떻게 든 중지하려고 할 수 있지만 FF 3, IE 8, Chrome 2 및 Opera 9가 처음에 HTML 속성 핸들러를 실행 한 다음 첨부 된 핸들러를 실행하는 것으로 보입니다 (jQuery로 테스트하지 않았습니다). 그러나 addEventListener 및 attachEvent). 그래서 .. 정확히 무엇을 이루려고하십니까?

그건 그렇고, 정규 표현식이 "valid ();"문자열을 추출 할 것이기 때문에 코드가 작동하지 않습니다. 이것은 확실히 함수가 아닙니다.


2

문자열 인 경우 항상 다음과 같은 형식이라고 가정 / 희망 할 수 있습니다.

return SomeFunction(arguments);

함수 이름을 구문 분석 한 다음 해당 함수가 다음을 사용하여 정의되었는지 확인합니다.

if (window[functionName]) { 
    // do stuff
}

이 해상도도 추가하려고했습니다. 문서 / 창 수준에서 함수를 등록하는 것을
— 잊지 마십시오

1

음, "return valid();" 이다 의이 수정 그래서, 문자열.

대신 연결된 함수가 있는지 확인하려면 다음을 시도해 볼 수 있습니다.

formId.onsubmit = function (){ /* */ }

if(typeof formId.onsubmit == "function"){
  alert("it's a function!");
}

1

혼란의 원인은 노드의 속성 과 해당 속성 간의 차이라고 생각합니다 .

다음을 사용하고 있습니다.

$("a.button").parents("form").attr("onsubmit")

onsubmit 속성 의 값 ( 문자열 이어야 함)을 직접 읽고 있습니다. 대신 노드 의 onsubmit 속성 에 액세스해야 합니다.

$("a.button").parents("form").prop("onsubmit")

다음은 빠른 테스트입니다.

<form id="form1" action="foo1.htm" onsubmit="return valid()"></form>
<script>
window.onload = function () {
    var form1 = document.getElementById("form1");

    function log(s) {
        document.write("<div>" + s + "</div>");
    }

    function info(v) {
        return "(" + typeof v + ") " + v;
    }

    log("form1 onsubmit property: " + info(form1.onsubmit));
    log("form1 onsubmit attribute: " + info(form1.getAttribute("onsubmit")));
};
</script> 

결과 :

form1 onsubmit 속성 : (함수) function onsubmit (event) {return valid (); }
form1 onsubmit 속성 : (문자열) valid () 반환

1
  if ( window.onsubmit ) {
     //
  } else {
     alert("Function does not exist.");
  }

1

하지가 typeof xxx === 'function'가장 빠른 최고의?

instanceof 및 _underscore에 비해 사용해 볼 수있는 벤치를 만들었습니다.

  1. instanceof (크롬 사용)보다 빠른 것 같습니다.
  2. 변수가 정의되지 않은 경우 오류가 발생하지 않습니다.

여기 벤치 : https://jsbench.me/qnkf076cqb/1


0

Chris West 와 같은 JavaScript 블로그에서 typeOf 함수 중 하나를 항상 사용할 수 있습니다 . typeOf()함수에 대해 다음과 같은 정의를 사용하면 작동합니다.

function typeOf(o){return {}.toString.call(o).slice(8,-1)}

이 함수 (전역 네임 스페이스에서 선언 됨)는 다음과 같이 사용할 수 있습니다.

alert("onsubmit is a " + typeOf(elem.onsubmit));

함수이면 "Function"이 반환됩니다. 문자열이면 "String"이 반환됩니다. 다른 가능한 값은 여기 에 표시 됩니다 .


0
// This should be a function, because in certain JavaScript engines (V8, for
// example, try block kills many optimizations).
function isFunction(func) {
    // For some reason, function constructor doesn't accept anonymous functions.
    // Also, this check finds callable objects that aren't function (such as,
    // regular expressions in old WebKit versions), as according to EcmaScript
    // specification, any callable object should have typeof set to function.
    if (typeof func === 'function')
        return true

    // If the function isn't a string, it's probably good idea to return false,
    // as eval cannot process values that aren't strings.
    if (typeof func !== 'string')
        return false

    // So, the value is a string. Try creating a function, in order to detect
    // syntax error.
    try {
        // Create a function with string func, in order to detect whatever it's
        // an actual function. Unlike examples with eval, it should be actually
        // safe to use with any string (provided you don't call returned value).
        Function(func)
        return true
    }
    catch (e) {
        // While usually only SyntaxError could be thrown (unless somebody
        // modified definition of something used in this function, like
        // SyntaxError or Function, it's better to prepare for unexpected.
        if (!(e instanceof SyntaxError)) {
            throw e
        }

        return false
    }
}

-3

다음과 같은 간단한 확인을 통해 존재 / 정의 여부를 알 수 있습니다.

if (this.onsubmit)
{
  // do stuff;
}

6
작동하지 않습니다. onsubmit이 비어 있지 않은 문자열 일 때 if는 TRUE로 주장합니다.
— Seb

1
무언가가 함수인지 테스트하는 끔찍한 방법-지시 된대로, 더 명확하게 : "진정한"것은이 코드가 "일을 수행"하게하고 예상 한 것과 다를 수 있습니다. this.onsubmit이 5 또는 "hello"또는 true로 평가되는 JavaScript의 다른 값으로 설정된 경우 예기치 않은 동작이 발생합니다.
— Jason Bunting

질문의 주제는 존재 여부를 확인하는 방법을 묻습니다. 그게 내가 제안한 전부입니다.
— Kon

실제로 게시 된 원본에는 "서식의 onsubmit 값이 함수인지 여부를 테스트해야 할 필요성"이 있다고 명시되어 있습니다. 귀하의 조건은 this.onsubmit이 기능인지 여부가 아닙니다. 테스트는 단순히 this.onsubmit이 "진정한"지 여부를 묻습니다
— Jason Bunting
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.