How to get function parameter names/values dynamically?

前端 未结 30 3132
说谎
说谎 2020-11-22 00:13

Is there a way to get the function parameter names of a function dynamically?

Let’s say my function looks like this:

function doSomething(param1, par         


        
30条回答
  •  清歌不尽
    2020-11-22 00:43

    Here is an updated solution that attempts to address all the edge cases mentioned above in a compact way:

    function $args(func) {  
        return (func + '')
          .replace(/[/][/].*$/mg,'') // strip single-line comments
          .replace(/\s+/g, '') // strip white space
          .replace(/[/][*][^/*]*[*][/]/g, '') // strip multi-line comments  
          .split('){', 1)[0].replace(/^[^(]*[(]/, '') // extract the parameters  
          .replace(/=[^,]+/g, '') // strip any ES6 defaults  
          .split(',').filter(Boolean); // split & filter [""]
    }  
    

    Abbreviated test output (full test cases are attached below):

    'function (a,b,c)...' // returns ["a","b","c"]
    'function ()...' // returns []
    'function named(a, b, c) ...' // returns ["a","b","c"]
    'function (a /* = 1 */, b /* = true */) ...' // returns ["a","b"]
    'function fprintf(handle, fmt /*, ...*/) ...' // returns ["handle","fmt"]
    'function( a, b = 1, c )...' // returns ["a","b","c"]
    'function (a=4*(5/3), b) ...' // returns ["a","b"]
    'function (a, // single-line comment xjunk) ...' // returns ["a","b"]
    'function (a /* fooled you...' // returns ["a","b"]
    'function (a /* function() yes */, \n /* no, */b)/* omg! */...' // returns ["a","b"]
    'function ( A, b \n,c ,d \n ) \n ...' // returns ["A","b","c","d"]
    'function (a,b)...' // returns ["a","b"]
    'function $args(func) ...' // returns ["func"]
    'null...' // returns ["null"]
    'function Object() ...' // returns []
    

    function $args(func) {  
        return (func + '')
          .replace(/[/][/].*$/mg,'') // strip single-line comments
          .replace(/\s+/g, '') // strip white space
          .replace(/[/][*][^/*]*[*][/]/g, '') // strip multi-line comments  
          .split('){', 1)[0].replace(/^[^(]*[(]/, '') // extract the parameters  
          .replace(/=[^,]+/g, '') // strip any ES6 defaults  
          .split(',').filter(Boolean); // split & filter [""]
    }  
    
    // test cases  
    document.getElementById('console_info').innerHTML = (
    [  
      // formatting -- typical  
      function(a,b,c){},  
      function(){},  
      function named(a, b,  c) {  
    /* multiline body */  
      },  
        
      // default values -- conventional  
      function(a /* = 1 */, b /* = true */) { a = a||1; b=b||true; },  
      function fprintf(handle, fmt /*, ...*/) { },  
      
      // default values -- ES6  
      "function( a, b = 1, c ){}",  
      "function (a=4*(5/3), b) {}",  
      
      // embedded comments -- sardonic  
      function(a, // single-line comment xjunk) {}
        b //,c,d
      ) // single-line comment
      {},  
      function(a /* fooled you{*/,b){},  
      function /* are you kidding me? (){} */(a /* function() yes */,  
       /* no, */b)/* omg! */{/*}}*/},  
      
      // formatting -- sardonic  
      function  (  A,  b  
    ,c  ,d  
      )  
      {  
      },  
      
      // by reference  
      this.jQuery || function (a,b){return new e.fn.init(a,b,h)},
      $args,  
      
      // inadvertent non-function values  
      null,  
      Object  
    ].map(function(f) {
        var abbr = (f + '').replace(/\n/g, '\\n').replace(/\s+|[{]+$/g, ' ').split("{", 1)[0] + "...";
        return "    '" + abbr + "' // returns " + JSON.stringify($args(f));
      }).join("\n") + "\n"); // output for copy and paste as a markdown snippet

提交回复
热议问题