Як перевірити, чи функція існує в JavaScript?


533

Мій код є

function getID( swfID ){
     if(navigator.appName.indexOf("Microsoft") != -1){
          me = window[swfID];
     }else{
          me = document[swfID];
     }
}

function js_to_as( str ){
     me.onChange(str);
}

Однак іноді моє onChangeне навантажує. Помилки Firebug з

me.onChange не є функцією

Я хочу деградувати витончено, тому що це не найважливіша особливість моєї програми. typeofдає ту саму помилку.

Будь-які пропозиції щодо того, як переконатися, що вона існує, а потім лише виконати onChange?

(Жоден із наведених нижче методів, за винятком того, як спробувати зловити одну роботу)


1
@SteveChambers Я це зробив. Дякую, що нагадали.
Алек Смарт


зловити Виняток. перевіри мою відповідь
Маттеус Барбоса

Відповіді:


1224

Спробуйте щось подібне:

if (typeof me.onChange !== "undefined") { 
    // safe to use the function
}

або ще краще (відповідно до коментаря UpTheCreek)

if (typeof me.onChange === "function") { 
    // safe to use the function
}

249
=== 'Функція' була б кращою! = 'Не визначено'
UpTheCreek

3
@James, оскільки ця заява насправді є undefinedвинятком у JavaScript. Я спробував це.
Майк Перренод

8
@UpTheCreek, це було б трохи небезпечно як загальне рішення, оскільки старіші версії IE трактують певні функції як об'єкти, наприклад typeof window.alert === 'object'.
Нойо

1
Чому б просто не використовувати if (me.onChange) { // do something }?
BornToCode

3
@BornToCode, тому що тоді me.onChangeможе бути все, що оцінює true, а не обов'язково функція (наприклад, це може бути булева, рядок тощо). Наприклад, див. Jsfiddle.net/j5KAF/1
Шнайдер

108

У мене була ця проблема.

if (obj && typeof obj === 'function') { ... }

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

Врешті-решт я зробив наступне:

if (typeof obj !== 'undefined' && typeof obj === 'function') { ... }

Колега вказав на мене, що перевірити, чи є, !== 'undefined'а потім === 'function'- це зайве, звичайно.

Простіше:

if (typeof obj === 'function') { ... }

Набагато чистіше і чудово працює.


1
У когось є ідея, чому кидається перший фрагмент коду ReferenceError? Це здається мені нелогічним.
сказавфаган

@saidfagan Дивіться визначення ReferenceError developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Міша Наследов

це працює для мене
NewBie1234

1
Будь-який мотив, чому typeof obj == 'function' буде недостатнім? ;-) Нагадування: оператор тестування строгої рівності має сенс лише тоді, коли статичний операнд порожній або нульовий або 0 або підлягає будь-якому подібному колу.
Фаб’єн Хаддаді

16

Якщо ви використовуєте eval для перетворення рядка у функцію, і ви хочете перевірити, чи існує цей метод eval'd, ви хочете використовувати typeof та функціональну рядок всередині eval :

var functionString = "nonexsitantFunction"
eval("typeof " + functionString) // returns "undefined" or "function"

Не переверніть це і спробуйте ввести типof на eval . Якщо ви зробите ReferenceError, вам буде кинуто:

var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined

21
eval == зло;)
Йети

1
Це може бути злом, але це дуже корисно, коли ім'я функції знаходиться в змінній.
Люк Кузенз

8
Зробити це можна без овалів. Приклад:var a = 'alert'; window[a]('it works');
zennin

15

Як щодо:

if('functionName' in Obj){
    //code
}

напр

var color1 = new String("green");
"length" in color1 // returns true
"indexOf" in color1 // returns true
"blablabla" in color1 // returns false

або щодо вашого випадку:

if('onChange' in me){
    //code
}

Див. Документи MDN .


але це рішення працює не кожен раз :( наприклад, якщо я хочу це знати, воно є lastIndexOf()в рядку (ми знаємо, що є, але теоретично), typeof String().lastIndexOf === "function"це правда, але 'lastIndexOf' in Stringпомилково.
iiic

10

Спробуйте typeof- шукайте, 'undefined'щоб сказати, що її немає 'function'для функції. JSFiddle для цього коду

function thisishere() {
    return false;
}
alert("thisishere() is a " + typeof thisishere);
alert("thisisnthere() is " + typeof thisisnthere);

Або як якщо:

if (typeof thisishere === 'function') {
    // function exists
}

Або зі зворотним значенням у одному рядку:

var exists = (typeof thisishere === 'function') ? "Value if true" : "Value if false";
var exists = (typeof thisishere === 'function') // Returns true or false

9

Не бачили цього: me.onChange && me.onChange (str);

В основному, якщо me.onChange не визначений (що буде, якщо він не був ініційований), він не виконає останню частину. Якщо me.onChange є функцією, вона виконає me.onChange (str).

Можна навіть піти далі і робити:

me && me.onChange && me.onChange(str);

на випадок, якщо я і асинхронний.


5
//Simple function that will tell if the function is defined or not
function is_function(func) {
    return typeof window[func] !== 'undefined' && $.isFunction(window[func]);
}

//usage

if (is_function("myFunction") {
        alert("myFunction defined");
    } else {
        alert("myFunction not defined");
    }

ваше рішення не зрозуміло, оскільки воно містить jQUery, що дивно в цей момент, я думаю, тому він видає помилки при простому тестуванні.
Т.Тодуа

@tazotodua - це сама пояснювальна функція. якщо ви хочете використовувати без jquery. просто видаліть && частину. це додаткова умова перевірити та уникнути помилок.
Мухаммед Тахір

Чи переважає стан лівого боку про &&те, що у jQuery isFunctionу правій частині &&немає?
SantiBailors

5

Для мене найпростіший спосіб:

function func_exists(fname)
{
  return (typeof window[fname] === 'function');
}

це правильна відповідь, тому що це рядковий літтерал. Я б сказав, що краще так, if ((typeof window["function_name"] !== 'undefined') && ((typeof window["function_name"] === 'function'))) { return true; } else { return false; }але це незначне коригування
Містер Хеліс

4

Я перейду ще на крок далі, щоб переконатися, що властивість справді є функцією

function js_to_as( str ){
     if (me && me.onChange && typeof me.onChange === 'function') {
         me.onChange(str);
     }
}


3

Мені подобається використовувати цей метод:

function isFunction(functionToCheck) {
  var getType = {};
  return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}

Використання:

if ( isFunction(me.onChange) ) {
    me.onChange(str); // call the function with params
}


3
function function_exists(function_name)
{
    return eval('typeof ' + function_name) === 'function';
}
alert(function_exists('test'));
alert(function_exists('function_exists'));

АБО

function function_exists(func_name) {
  //  discuss at: http://phpjs.org/functions/function_exists/
  // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // improved by: Steve Clay
  // improved by: Legaev Andrey
  // improved by: Brett Zamir (http://brett-zamir.me)
  //   example 1: function_exists('isFinite');
  //   returns 1: true

  if (typeof func_name === 'string') {
    func_name = this.window[func_name];
  }
  return typeof func_name === 'function';
}

1
Будь ласка, пояснення.
Гуфран Хасан

У двох випадках просто виклик function_exists з назвою параметра функції, щоб перевірити існування, повертає bool.
Мохаммед Лотфі

3

Поставте подвійний знак оклику, тобто !! перед назвою функції, яку потрібно перевірити. Якщо вона існує, вона поверне справжню.

function abc(){
}
!!window.abc; // return true
!!window.abcd; // return false

3

Кільками слів: зловити виняток.

Я дуже здивований, поки ніхто не відповідав і не коментував цю програму.

Детальніше: Тут наводиться приклад, коли я намагаюся співставити функцію, префіксовану mask_ і суфіксирується полем форми "name". Якщо JavaScript не знаходить цю функцію, він повинен викинути ReferenceError, з яким ви можете керуватися, як хочете, на розділ улов.

function inputMask(input) {
  try {
    let maskedInput = eval("mask_"+input.name);

    if(typeof maskedInput === "undefined")
        return input.value;
    else
        return eval("mask_"+input.name)(input);

  } catch(e) {
    if (e instanceof ReferenceError) {
      return input.value;
    }
  }
}


2

Без жодних умов

me.onChange=function(){};

function getID( swfID ){
     if(navigator.appName.indexOf("Microsoft") != -1){
          me = window[swfID];
     }else{
          me = document[swfID];
     }
}

function js_to_as( str ){
     me.onChange(str);
}

2

Я б підозрював, що meнеправильно призначається завантаження.

Переміщення виклику get_ID у подію onclick повинно подбати про це.

Очевидно, ви можете додатково потрапити в пастку, як було зазначено раніше:

function js_to_as( str) {
  var me = get_ID('jsExample');
  if (me && me.onChange) {
    me.onChange(str);
  }
}

2

Я завжди перевіряю так:

if(!myFunction){return false;}

просто поставте його перед будь-яким кодом, який використовує цю функцію


2

У мене був випадок, коли ім’я функції змінювалося залежно від змінної (var 'x' в даному випадку), доданої до імені функцій. Це працює:

if ( typeof window['afunction_'+x] === 'function' ) { window['afunction_'+x](); } 


2

Я спробував прийняту відповідь; проте:

console.log(typeof me.onChange);

повертає "невизначено". Я помітив, що специфікація зазначає подію під назвою "onchange" замість "onChange" (зауважте camelCase).

Зміна оригінальної прийнятої відповіді на наступне працювало для мене:

if (typeof me.onchange === "function") { 
  // safe to use the function
}

2

Якщо ви перевіряєте функцію, яка є плагіном jQuery, вам потрібно використовувати $ .fn.myfunction

if (typeof $.fn.mask === 'function') {
    $('.zip').mask('00000');
}

2

Я також шукав елегантне рішення цієї проблеми. Після багато роздумів я знайшов цей підхід найкращим.

const func = me.onChange || (str => {}); func(str);


Якщо ви збираєтеся на мінімалізм, ви також можете це зробити: (me.onChange||(_=>_))()Виконайте функцію, якщо вона існує, інакше нічого не зробить.
JSideris

Краще me.onChange && me.onChange()запобігти визначенню функції пустоти.
necrifede

2

Сучасний Javascript для порятунку!

Це може не мати великого шансу побачити довгий список відповідей, але це зараз вирішено * на мовному рівні за допомогою нового синтаксису необов’язкового ланцюжка

me.onChange?.(str)

Це так просто - onChangeназивається лише тоді, коли він існує .

Якщо onChangeцього не існує, нічого не відбувається, і вираз повертається, undefinedтому, якщо він має значення повернення, яке ви використовували б іншим способом, ви можете просто перевірити це значення, !== undefinedперш ніж продовжувати.

Застереження про край краю - якщо onChange він існує, але це не функція, ви отримуєте TypeError. Це, як ви і очікували, це те саме, що намагатися викликати будь-яку нефункціональну функцію, але варто чітко зазначити, що опціональний ланцюжок не робить ніяких магічних дій, щоб зникнути.

* Ну, технічно кажучи, необов'язковий ланцюжок все ще є пропозицією TC39 етапу 4, тому ще не є специфікацією ECMAScript, але 4-й етап означає, що він завершений, і його включення по суті гарантується, воно просто чекає надходження нової версії. Ви можете використовувати синтаксис у його остаточній версії сьогодні через Babel з впевненістю, що він не зміниться. Це навіть у Typescript!


1

Ось робоче і просте рішення для перевірки існування функції та її активізації динамічно іншою функцією;

Функція спуску

function runDynamicFunction(functionname){ 

    if (typeof window[functionname] == "function") { //check availability

        window[functionname]("this is from the function it"); // run function and pass a parameter to it
    }
}

і тепер ви можете динамічно генерувати функцію, можливо, використовуючи подібний php

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

тепер ви можете викликати функцію за допомогою динамічно генерованої події

<?php

$name_frm_somware ="runThis_func";

echo "<input type='button' value='Button' onclick='runDynamicFunction(\"".$name_frm_somware."\");'>";

?>

точний потрібний вам HTML код

<input type="button" value="Button" onclick="runDynamicFunction('runThis_func');">

0
    function sum(nb1,nb2){

       return nb1+nb2;
    }

    try{

      if(sum() != undefined){/*test if the function is defined before call it*/

        sum(3,5);               /*once the function is exist you can call it */

      }

    }catch(e){

      console.log("function not defined");/*the function is not defined or does not exists*/
    }

0

І тут є це ...

( document.exitPointerLock || Function )();

привіт магістр, хороший, але що ви думаєте про те, щоб зловити Виняток? перевіри мою відповідь
Маттеус Барбоса

Привіт, дякую за замітку. Ваше рішення приємне. Я намагаюся уникати парадигми "пробувати", коли це можливо чи простіше, або, можливо, це передбачається / нав'язується стороною допомогою. "Eval" також нахмуриться з різних причин, один з них схожий на спробу іншої обгортки, щоб затримати час. Є альтернативи eval, які теж можуть "кинути". Я думаю, що "нова функція (parms, body)", можливо, може призвести до помилки, але, мабуть, наступне питання для мене - порівняння швидкості, інше, ніж найкраще зменшення розміру коду (для мене швидше.) [Гм, це виглядає новим. Я не пробував це jsben.ch]
Майстер Джеймс

ммм дуже цікавий момент щодо виклику нової функції. сміливо надсилайте свої пропозиції щодо змін на мою відповідь. дякую багато
Маттеус Барбоса

Я маю на увазі, навіть у bash, використовуючи 'source myScript.sh', ви зможете «експортувати» через псевдоніми тощо. Це як би класи та бібліотеки завжди були властивою будь-якому коду. У вас повинен бути код перевірки js-перекладача, якщо він точно не санкціонований. Я вбудував його в одну функцію, що є ще одним цікавим завданням, щоб допомогти зрозуміти найпростіший аксіоматичний характер коду, і навіть час виконання не виходить за межі будь-кого.
Майстер Джеймс

0

Спробуйте це:

Window.function_exists=function(function_name,scope){
//Setting default scope of none is provided
If(typeof scope === 'undefined') scope=window;
//Checking if function name is defined
If (typeof function_name === 'undefined') throw new 
Error('You have to provide an valid function name!');
//The type container
var fn= (typeof scope[function_name]);
//Function type
If(fn === 'function') return true;
//Function object type
if(fn.indexOf('function')!== false) return true; 
return false;
}

Майте на увазі, що я пишу це за допомогою свого мобільного телефону, може містити деякі великі проблеми та / або інші виправлення, потрібні, наприклад, наприклад, ім'я функцій

Якщо ви хочете, щоб функція на зразок PHP перевірила, чи встановлено var:

Window.isset=function (variable_con){
If(typeof variable_con !== 'undefined') return true;
return false;
}

0

Щоб проілюструвати попередні відповіді, ось короткий фрагмент JSFiddle:

function test () {
console.log()

}

console.log(typeof test) // >> "function"

// implicit test, in javascript if an entity exist it returns implcitly true unless the element value is false as :
// var test = false
if(test){ console.log(true)}
else{console.log(false)}

// test by the typeof method
if( typeof test === "function"){ console.log(true)}
else{console.log(false)}


// confirm that the test is effective : 
// - entity with false value
var test2 = false
if(test2){ console.log(true)}
else{console.log(false)}

// confirm that the test is effective :
// - typeof entity
if( typeof test ==="foo"){ console.log(true)}
else{console.log(false)}

/* Expected :
function
true 
true 
false
false
*/


0
// just pass your tested function name instead of myFunctionName
if ( $.isFunction($.fn.myFunctionName) ) {
    console.log( 'write your code here.' );
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.