How to check if function exists inside another function using Javascript

2.2k views Asked by At

I`m trying to build an function that load script on-demand. That is my current code:

function loadScript(src, name = null)
{
    var dfd = jQuery.Deferred();

    if (name === null) {
        name = src.split(/\\|\//); // split by folder separator 
        name = name[(name.length - 1)].split('.'); // catch last index & split by extension 
        name.splice(name.length - 1, 1) // Remove last
        name = name.join('.'); // add points in the middle of file name
    }

    if ( typeof name === 'function' ) return dfd.promise().resolve(name);

    $.getScript( src )
    .done(function( script, textStatus ) {
        dfd.resolve(name);
    })
    .fail(function( jqxhr, settings, exception ) {
        dfd.reject(exception);
    });

    return dfd.promise();
}

My problem is on this part of code:

if ( typeof name === 'function' ) return dfd.promise().resolve(name);

Where name is a variable that contains desired function name to check, but not the real function name, causing function never evaluate as 'function'.

I tried:

typeof `${name}` // resulting a "string" 

eval("typeof name === 'function'") // But my node system not accept eval due to a potentially security risk

How many alternatives that I have ?

3

There are 3 answers

4
Guerric P On

You could do typeof eval(name) === function or if the function is a global, typeof window[name] === function

Demo:

(function() {
    function test() {}
    (function(name) {
        console.log(typeof eval(name) === 'function');
    })('test');
})();

0
David Watson On

Quick and dirty:

if ( typeof name === 'string' && typeof eval(name) === 'function' ) return dfd.promise().resolve(name);

since you probably want to double-check that name is actually a before passing it to eval. You probably also want to further validate it if it's coming from user input as you could be opening yourself up to script injections.

0
OO7 On

Hope this could helps anyone;

const getFunc = (s) => {
   const a = s.split(".");
   let obj = window, i = 0;
   while (i < a.length && (obj = obj[a[i++]]) !== undefined);
   if (typeof obj === "function") return obj;
};

console.log(getFunc("Infinity.isFloat"));