programing

값이 함수인지 테스트

nasanasas 2020. 9. 16. 07:48
반응형

값이 함수인지 테스트


폼의 값이 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;
    }
} );

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


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

시험

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

간단히 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".

I hope this might clarify a few things. Then again, if you want to know if such property (or any identifier for the matter) is a function and callable, the typeof operator should do the trick. Although I'm not sure if it works properly across multiple frames.

Cheers


What browser are you using?

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

This gives me "function" in IE7 and FireFox.


using a string based variable as example and making use instanceof Function You register the function..assign the variable...check the variable is the name of function...do pre-process... assign the function to new var...then call the 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();
}

Make sure you are calling typeof on the actual function, not a string literal:

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

typeof "x"; // returns "string"

typeof x; // returns "function"

You can try modifying this technique to suit your needs:

 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.');
 }

form.onsubmit will always be a function when defined as an attribute of HTML the form element. It's some sort of anonymous function attached to an HTML element, which has the this pointer bound to that FORM element and also has a parameter named event which will contain data about the submit event.

Under these circumstances I don't understand how you got a string as a result of a typeof operation. You should give more details, better some code.

Edit (as a response to your second edit):

I believe the handler attached to the HTML attribute will execute regardless of the above code. Further more, you could try to stop it somehow, but, it appears that FF 3, IE 8, Chrome 2 and Opera 9 are executing the HTML attribute handler in the first place and then the one attached (I didn't tested with jQuery though, but with addEventListener and attachEvent). So... what are you trying to accomplish exactly?

By the way, your code isn't working because your regular expression will extract the string "valid();", which is definitely not a function.


If it's a string, you could assume / hope it's always of the form

return SomeFunction(arguments);

parse for the function name, and then see if that function is defined using

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

Well, "return valid();" is a string, so that's correct.

If you want to check if it has a function attached instead, you could try this:

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

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

I think the source of confusion is the distinction between a node's attribute and the corresponding property.

You're using:

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

You're directly reading the onsubmit attribute's value (which must be a string). Instead, you should access the onsubmit property of the node:

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

Here's a quick test:

<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> 

This yields:

form1 onsubmit property: (function) function onsubmit(event) { return valid(); }
form1 onsubmit attribute: (string) return valid()

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

You can always use one of the typeOf functions on JavaScript blogs such as Chris West's. Using a definition such as the following for the typeOf() function would work:

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

This function (which is declared in the global namespace, can be used like this:

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

If it is a function, "Function" will be returned. If it is a string, "String" will be returned. Other possible values are shown here.


// 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
    }
}

A simple check like this will let you know if it exists/defined:

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

참고URL : https://stackoverflow.com/questions/798340/testing-if-value-is-a-function

반응형