774

My code is

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

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

However, sometimes my onChange does not load. Firebug errors with

me.onChange is not a function

I want to degrade gracefully because this is not the most important feature in my program. typeof gives the same error.

Any suggestions on how to make sure that it exists and then only execute onChange?

(None of the methods below except try catch one work)

animuson
  • 53,861
  • 28
  • 137
  • 147
Alec Smart
  • 94,115
  • 39
  • 120
  • 184
  • Possible duplicate of [How to tell if a Javascript function is defined](https://stackoverflow.com/questions/85815/how-to-tell-if-a-javascript-function-is-defined) – Tot Zam Aug 03 '17 at 21:16

34 Answers34

1575

Try something like this:

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

or better yet (as per UpTheCreek upvoted comment)

if (typeof me.onChange === "function") { 
    // safe to use the function
}
j0k
  • 22,600
  • 28
  • 79
  • 90
Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
  • 10
    @UpTheCreek, it would be a bit dangerous as a general solution since older versions of IE treat certain functions as objects, e.g. `typeof window.alert === 'object'`. – Noyo Sep 04 '13 at 13:51
  • 3
    Why not just use `if (me.onChange) { // do something }` ? – BornToCode Jan 09 '14 at 10:21
  • 4
    @BornToCode because then `me.onChange` could be anything evaluating to `true`, not necessarily a function (e.g. it could be a boolean, a string, etc). For example see http://jsfiddle.net/j5KAF/1/ – Ohad Schneider Apr 13 '14 at 07:53
  • 1
    @UpTheCreek and @Noyo: I missed your comments and ran into the issue. I just turned the test into: `((typeof me.onChange === "function") || (typeof me.onChange === "object"))` Works fine down to ie8 in my case. – Swiss Mister Jan 22 '15 at 16:58
  • Why === and !==? == and != should be fine, as typeof returns string – l00k Aug 24 '16 at 03:14
  • @l00k Id imagine its to satify jslinting tools. Javascript is horrible for loose data typing, so if you can use !== and === instead of != and ==, then its usually a great practice to just do it by default. There is rarely a reason not to. – carpii Oct 06 '16 at 20:38
  • 2
    Just to point out the obvious `typeof me.onChange === "function"` fails if that global `me` is undefined. – Mark Schultheiss Dec 16 '17 at 17:11
171

Modern JavaScript to the rescue!

me.onChange?.(str)

The Optional Chaining syntax (?.) solves this

In the example above, if a me.onChange property exists and is a function, it is called.

If no me.onChange property exists, nothing happens: the expression just returns undefined.

Note - if a me.onChange property exists but is not a function, a TypeError will be thrown just like when you call any non-function as a function in JavaScript. Optional Chaining doesn't do any magic to make this go away.

davnicwil
  • 28,487
  • 16
  • 107
  • 123
  • This can't check if a bare function exists though. If `me` is undefined, this will throw. – duhaime Feb 01 '22 at 01:39
  • 2
    @duhaime `me` being undefined is a separate concern (the function just happens to be on a `me` object in the question) - but, if you did need to check first if `me` is defined you can *also* do that with optional chaining: `me?.onChange?.(str)` – davnicwil Feb 01 '22 at 17:17
  • If you run `me?.onChange?.(str)` in your dev console it'll bomb. Though if you know the global context that can work `window?.$me?.onChange?.(str)` – duhaime Feb 02 '22 at 03:08
  • Ah, interesting one! Yeah I guess that'd be a `ReferenceError` if `me` is not even *declared* (as opposed to declared but `undefined`). Looking at the question that's indeed the case there if that's the entire code, I was assuming it was just a snippet with `me` implied to be declared somewhere else. Nice catch! – davnicwil Feb 02 '22 at 16:57
  • 3
    A cautionary tale about using this: https://blog.jim-nielsen.com/2022/a-web-for-all/ – cbirdsong Jun 16 '22 at 19:03
160

I had this problem. if (obj && typeof obj === 'function') { ... } kept throwing a reference error if obj happened to be undefined, so in the end I did the following:

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

However, a colleague pointed out to me that checking if it's !== 'undefined' and then === 'function' is redundant, thus:

Simpler:

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

Much cleaner and works great.

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
Misha Nasledov
  • 2,003
  • 1
  • 15
  • 18
  • 1
    Anyone has idea why the first code snippet throws `ReferenceError`? That seems illogical to me. – saidfagan Aug 21 '19 at 08:03
  • @saidfagan See the definition of `ReferenceError` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError – Misha Nasledov Sep 24 '19 at 22:38
  • 3
    Any motive why typeof obj == 'function' would be insufficient? ;-) Reminder: strict equality test operator only makes sense when the static operand is empty or null or 0 or subject to any cast amalgame like this. – Fabien Haddadi Apr 30 '20 at 19:18
27

How about:

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

e.g.

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

or as for your case:

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

See MDN docs.

Nasser Al-Wohaibi
  • 4,562
  • 2
  • 36
  • 28
  • 1
    but this solution is not working everytime :( for example if I want to know it there is `lastIndexOf()` in string (we know, that is, but theoretically) `typeof String().lastIndexOf === "function"` it's true, but `'lastIndexOf' in String` is false. – iiic Nov 29 '19 at 13:28
21

If you're using eval to convert a string to function, and you want to check if this eval'd method exists, you'll want to use typeof and your function string inside an eval:

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

Don't reverse this and try a typeof on eval. If you do a ReferenceError will be thrown:

var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined
dhulihan
  • 11,053
  • 9
  • 40
  • 45
15

Try typeof -- Look for 'undefined' to say it doesn't exist, 'function' for a function. JSFiddle for this code

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

Or as an if:

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

Or with a return value, on a single line:

var exists = (typeof thisishere === 'function') ? "Value if true" : "Value if false";
var exists = (typeof thisishere === 'function') // Returns true or false
Mat Carlson
  • 543
  • 3
  • 12
14

Didn't see this suggested: me.onChange && me.onChange(str);

Basically if me.onChange is undefined (which it will be if it hasn't been initiated) then it won't execute the latter part. If me.onChange is a function, it will execute me.onChange(str).

You can even go further and do:

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

in case me is async as well.

Samir Alajmovic
  • 3,247
  • 3
  • 26
  • 28
12

For me the easiest way :

function func_exists(fname)
{
  return (typeof window[fname] === 'function');
}
Tu4n3r
  • 441
  • 5
  • 10
  • this is the correct answer, because it's a string litteral .. I would say it better like this `if ((typeof window["function_name"] !== 'undefined') && ((typeof window["function_name"] === 'function'))) { return true; } else { return false; }` but it's a minor adjustment – Mr Heelis Dec 20 '18 at 10:26
10

Put double exclamation mark i.e !! before the function name that you want to check. If it exists, it will return true.

function abc(){
}
!!window.abc; // return true
!!window.abcd; // return false
7
//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");
    }
Muhammad Tahir
  • 2,351
  • 29
  • 25
  • your solution is not clear, as it containt jQUery, which is odd at this moment i think, so it throws errors when simple testing. – T.Todua Apr 23 '15 at 22:54
  • @tazotodua it is self explanatory function. if you want to use without jquery. just remove the && part. that is an extra condition to check and to avoid errors. – Muhammad Tahir Apr 24 '15 at 04:33
  • Does the condition at the left side of the `&&` take care of something that the jQuery's `isFunction` at the right side of the `&&` doesn't ? – SantiBailors Mar 24 '17 at 15:16
7
function function_exists(function_name)
{
    return eval('typeof ' + function_name) === 'function';
}
alert(function_exists('test'));
alert(function_exists('function_exists'));

OR

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';
}
Mohammad Lotfi
  • 369
  • 5
  • 16
6
function js_to_as( str ){
     if (me && me.onChange)
         me.onChange(str);
}
MiffTheFox
  • 21,302
  • 14
  • 69
  • 94
6

I'll go 1 step further to make sure the property is indeed a function

function js_to_as( str ){
     if (me && me.onChange && typeof me.onChange === 'function') {
         me.onChange(str);
     }
}
Alex
  • 34,776
  • 10
  • 53
  • 68
6

Here is a working and simple solution for checking existence of a function and triggering that function dynamically by another function;

Trigger function

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

and you can now generate the function dynamically maybe using php like this

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

now you can call the function using dynamically generated event

<?php

$name_frm_somware ="runThis_func";

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

?>

the exact HTML code you need is

<input type="button" value="Button" onclick="runDynamicFunction('runThis_func');">
Brian C
  • 837
  • 1
  • 10
  • 20
Aylian Craspa
  • 422
  • 5
  • 11
5

I like using this method:

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

Usage:

if ( isFunction(me.onChange) ) {
    me.onChange(str); // call the function with params
}
David Douglas
  • 10,377
  • 2
  • 55
  • 53
5

The Underscore.js library defines it in the isFunction method as this (which comments suggest may cater for some browser bugs)

typeof obj == 'function' || false

http://underscorejs.org/docs/underscore.html#section-143

PandaWood
  • 8,086
  • 9
  • 49
  • 54
5

I had the case where the name of the function varied according to a variable (var 'x' in this case) added to the functions name. This works:

if ( typeof window['afunction_'+x] === 'function' ) { window['afunction_'+x](); } 
Sebastian H
  • 109
  • 1
  • 6
5

If you're checking for a function that is a jQuery plugin, you need to use $.fn.myfunction

if (typeof $.fn.mask === 'function') {
    $('.zip').mask('00000');
}
Evg
  • 25,259
  • 5
  • 41
  • 83
Lucas Bustamante
  • 15,821
  • 7
  • 92
  • 86
5

In a few words: catch the exception.

I am really surprised nobody answered or commented about Exception Catch on this post yet.

Detail: Here goes an example where I try to match a function which is prefixed by mask_ and suffixed by the form field "name". When JavaScript does not find the function, it should throw an ReferenceError which you can handle as you wish on the catch section.

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;
    }
  }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Matteus Barbosa
  • 2,409
  • 20
  • 21
4

With no conditions

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);
}
Itay Moav -Malimovka
  • 52,579
  • 61
  • 190
  • 278
4

I would suspect that me is not getting correctly assigned onload.

Moving the get_ID call into the onclick event should take care of it.

Obviously you can further trap as previously mentioned:

function js_to_as( str) {
  var me = get_ID('jsExample');
  if (me && me.onChange) {
    me.onChange(str);
  }
}
wombleton
  • 8,336
  • 1
  • 28
  • 30
4

I always check like this:

if(!myFunction){return false;}

just place it before any code that uses this function

el Dude
  • 5,003
  • 5
  • 28
  • 40
4

This simple jQuery code should do the trick:

if (jQuery.isFunction(functionName)) {
    functionName();
}
4

I have tried the accepted answer; however:

console.log(typeof me.onChange);

returns 'undefined'. I've noticed that the specification states an event called 'onchange' instead of 'onChange' (notice the camelCase).

Changing the original accepted answer to the following worked for me:

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

I have also been looking for an elegant solution to this problem. After much reflection, I found this approach best.

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

Julian
  • 334
  • 4
  • 18
  • If you're going for minimalizm, you could also do this: `(me.onChange||(_=>_))()` Will execute the function if it exists, otherwise will do nothing. – JSideris Sep 22 '19 at 21:46
  • It is better `me.onChange && me.onChange()` to prevent define a void function. – necrifede Feb 27 '20 at 12:06
3

I would suggest using:

function hasMethod(subject, methodName) {
  return subject != null && typeof subject[methodName] == "function";
}

The first check subject != null filters out nullish values (null and undefined) which don't have any properties. Without this check subject[methodName] could throw an error:

TypeError: (undefined|null) has no properties

Checking for only a truthy value isn't enough, since 0 and "" are both falsy but do have properties.

After validating that subject is not nullish you can safely access the property and check if it matches typeof subject[methodName] == "function".


Applying this to your code you can now do:

if (hasMethod(me, "onChange")) {
  me.onChange(str);
}
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
2

To illustrate the preceding answers, here a quick JSFiddle snippet :

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
*/
HoCo_
  • 1,302
  • 4
  • 16
  • 33
1
    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*/
    }
Ir Calif
  • 460
  • 6
  • 7
1

And then there is this...

( document.exitPointerLock || Function )();
Master James
  • 1,691
  • 15
  • 19
  • hello Master, good one, but what do you think about catching the Exception? check my answer – Matteus Barbosa Oct 24 '19 at 18:40
  • Hi thanks for the note. Your solution is admirable. I try to avoid the 'try-catch' paradigm whenever possible or easier, or maybe it's been implied/imposed by a 3rd party aid. 'Eval' is also frowned upon for various reasons one being like try-catch another wrapper so time delays. There are alternatives to eval that might 'throw' too. I think 'new Function(parms, body)' would maybe throw you an error, but I guess the next question for me is speed comparisons, other then just best code size reduction (implies faster to me). [Hmm this looks new. I've not tried it jsben.ch] – Master James Nov 01 '19 at 06:40
  • mmm rly interesting point about calling new Function instead. feel free to submit your changes suggestions to my answer. thanks alot – Matteus Barbosa Nov 01 '19 at 11:40
  • Ya I mean even in bash using 'source myScript.sh' will let you 'export' via aliases etc. it's like classes and libraries have always been an inherent property of any and all code. You should have a js interpreter check code if it's not been sanctioned for sure. I built one in a single function, which is another fun challenge to help understand the simplest axiomatic nature of code, and even a run-time is not beyond anyone's ability. – Master James Nov 08 '19 at 07:16
1

Try this one:

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

Be aware that I've write this with my cellphone Might contain some uppercase issues and/or other corrections needed like for example functions name

If you want a function like PHP to check if the var is set:

Window.isset=function (variable_con){
If(typeof variable_con !== 'undefined') return true;
return false;
}
1
// just pass your tested function name instead of myFunctionName
if ( $.isFunction($.fn.myFunctionName) ) {
    console.log( 'write your code here.' );
}
1

I prefer it using lodash library as below (looks much cleaner):

if (_.has(me, "onChange")) {
   // your desired code here
}

// or generic one like

if (_.has(this, "some property or function name")) {
   // your desired code here
}
Imran Zahoor
  • 2,521
  • 1
  • 28
  • 38
0

This will verify if the function exists, if so it will be executed

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

Thus the error TypeError: me.onChange is not a function is prevent.

necrifede
  • 781
  • 5
  • 8
-1
function isFunction( o ) { return null !== o && "function" === typeof o && !!o.apply; }
isherwood
  • 58,414
  • 16
  • 114
  • 157
cskwg
  • 790
  • 6
  • 13