Проверка того, является ли значение функцией

StackOverflow https://stackoverflow.com/questions/798340

  •  18-09-2019
  •  | 
  •  

Вопрос

Мне нужно проверить, соответствует ли значение формы onsubmit является функцией.Формат, как правило, onsubmit="return valid();".Есть ли способ определить, является ли это функцией и можно ли ее вызвать?Использование typeof просто возвращает, что это строка, что мне не очень помогает.

Редактировать:Конечно, я понимаю, что "return valid();" - это строка.У меня есть 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:Вот новый код.Похоже, мне все еще приходится использовать eval , потому что вызов form.submit() не запускает существующие onsubmits.

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's, я нахожу его и оцениваю() его сам.Но я хотел бы проверить, существует ли функция перед просто 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>

Редактировать :отсутствует параметр f в функции testOnsubmitAndSubmit

Вышесказанное должно работать независимо от того, назначаете ли вы onsubmit HTML атрибут или назначьте его в JavaScript:

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

Другие советы

Попробуй

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

Вы могли бы просто использовать typeof оператор вместе с троичным оператором для краткости:

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

Если это функция, мы вызываем ее и возвращаем возвращаемое значение, в противном случае просто возвращаем true

Редактировать:

Я не совсем уверен, что вы на самом деле хотите сделать, но я попытаюсь объяснить, что может произойти.

Когда вы заявляете о своем onsubmit код внутри вашего html превращается в функцию и, таким образом, его можно вызвать из "мира" JavaScript.Это означает, что эти два метода эквивалентны:

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

Эти две функции будут обеими, и обе будут вызываемыми.Вы можете протестировать любой из них, используя typeof оператор, который должен выдать тот же результат: "function".

Теперь, если вы присвоите строку свойству "onsubmit" с помощью JavaScript, она останется строкой, следовательно, не может быть вызвана.Обратите внимание, что если вы примените typeof оператор против этого, вы получите "string" вместо того , чтобы "function".

Я надеюсь, что это могло бы прояснить некоторые вещи.С другой стороны, если вы хотите знать, является ли такое свойство (или любой соответствующий идентификатор) функцией и может ли оно вызываться, то typeof оператор должен сделать свое дело.Хотя я не уверен, что это работает должным образом в нескольких кадрах.

Ваше здоровье

Какой браузер вы используете?

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

Это дает мне "function" в IE7 и FireFox.

Убедитесь, что вы вызываете typeof для фактической функции, а не для строкового литерала:

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

typeof "x"; // returns "string"

typeof x; // returns "function"

используя в качестве примера переменную на основе строк и используя instanceof Function Вы регистрируете функцию .. присваиваете переменную ... проверяете, соответствует ли переменная имени function...do предварительная обработка...назначьте функцию новой переменной ... затем вызовите функцию.

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();
}

Вы можете попробовать изменить эта техника в соответствии с вашими потребностями:

 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 всегда будет функцией, когда определен как атрибут HTML элемента form.Это своего рода анонимная функция, прикрепленная к HTML-элементу, который имеет это указатель привязан к этому элементу ФОРМЫ, а также имеет параметр с именем event который будет содержать данные о событии отправки.

При таких обстоятельствах я не понимаю, как вы получили строку в результате операции typeof .Вам следует предоставить больше деталей, лучше какой-нибудь код.

Редактировать (в ответ на вашу вторую правку):

Я полагаю, что обработчик, прикрепленный к атрибуту HTML, будет выполняться независимо от приведенного выше кода.Более того, вы могли бы попытаться как-то остановить это, но, похоже, что FF 3, IE 8, Chrome 2 и Opera 9 в первую очередь выполняют обработчик атрибута HTML, а затем прикрепленный (хотя я тестировал не с jQuery, а с addEventListener и attachEvent).Итак...чего именно вы пытаетесь достичь?

Кстати, ваш код не работает, потому что ваше регулярное выражение извлечет строку "valid();", которая определенно не является функцией.

Если это строка, вы могли бы предположить / надеяться, что она всегда имеет вид

return SomeFunction(arguments);

проанализируйте имя функции, а затем посмотрите, определена ли эта функция с помощью

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

Что ж, "return valid();" является строка, так что это правильно.

Если вы хотите проверить, есть ли у него вместо этого подключенная функция, вы могли бы попробовать это:

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

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

Я думаю, что источником путаницы является различие между атрибут и соответствующий свойство.

Ты используешь:

$("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 property: (function) function onsubmit(event) { return valid(); }
form1 onsubmit attribute: (string) return valid()
  if ( window.onsubmit ) {
     //
  } else {
     alert("Function does not exist.");
  }

Вы всегда можете использовать одну из функций typeOf в блогах JavaScript, таких как Криса Уэста.Используя определение , подобное следующему , для typeOf() функция будет работать:

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

Эта функция (которая объявлена в глобальном пространстве имен, может использоваться следующим образом:

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

Если это функция, то будет возвращено "Function".Если это строка, будет возвращено "String".Показаны другие возможные значения здесь.

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

Простая проверка, подобная этой, позволит вам узнать, существует ли она / определена:

if (this.onsubmit)
{
  // do stuff;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top