값이 함수인지 테스트


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.