簡體   English   中英

是否有可能反映Javascript函數的參數?

[英]Is it possible to reflect the arguments of a Javascript function?

是否有可能將Javascript函數的所有參數都寫入接受? (我知道所有Javascript函數參數都是“可選的”)? 如果沒有,是否可以獲得參數的數量? 例如,在PHP中,可以使用:

$class = new ReflectionClass('classNameHere');
$methods = $class->getMethods();
foreach ($methods as $method) {
    print_r($method->getParameters());
}

...或類似的東西,我有一段時間沒有碰過PHP,所以上面的例子可能不正確。

提前致謝!

編輯:不幸的是,我必須能夠在函數體外獲取參數...對不起澄清,但感謝您當前的答案!

這個新版本也處理胖箭頭功能......

args = f => f.toString ().replace (/[\r\n\s]+/g, ' ').
              match (/(?:function\s*\w*)?\s*(?:\((.*?)\)|([^\s]+))/).
              slice (1,3).
              join ('').
              split (/\s*,\s*/);

function ftest (a,
                 b,
                 c) { }

let aftest = (a,
                 b,
                 c) => a + b / c;

console.log ( args (ftest),  // = ["a", "b", "c"] 
              args (aftest), // = ["a", "b", "c"]
              args (args)    // = ["f"]
             );

以下是我認為您正在尋找的內容:

 function ftest (a,
                 b,
                 c) { }
 var args = ftest.toString ().
              replace (/[\r\n\s]+/g, ' ').
              match (/function\s*\w*\s*\((.*?)\)/)[1].split (/\s*,\s*/);

args將是測試參數名稱的數組,即['a','b','c']

如果ftest是函數,則args將是參數名稱的數組。 如果ftest沒有參數,則數組將為空。 如果ftest未通過正則表達式匹配,則args的值將為null ,即它不是函數。

有可能獲得javascript的所有形式參數名稱:

var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;

function formalParameterList(fn) {
   var fnText,argDecl;
   var args=[];
   fnText = fn.toString().replace(STRIP_COMMENTS, '');
   argDecl = fnText.match(FN_ARGS); 

   var r = argDecl[1].split(FN_ARG_SPLIT);
   for(var a in r){
      var arg = r[a];
      arg.replace(FN_ARG, function(all, underscore, name){
         args.push(name);
      });
   }
   return args;
 }

這可以通過這種方式測試:

 var expect = require('expect.js');
 expect( formalParameterList(function() {} )).to.eql([]);
 expect( formalParameterList(function () {} )).to.eql([]);
 expect( formalParameterList(function /*  */ () {} )).to.eql([]);
 expect( formalParameterList(function (/* */) {} )).to.eql([]);
 expect( formalParameterList(function ( a,   b, c  ,d /* */, e) {} )).to.eql(['a','b','c','d','e']);

注意:此技術與AngularJs的$ injector一起使用,並在annotate函數中實現。 (見https://github.com/angular/angular.js/blob/master/src/auto/injector.js並在相應的單元測試https://github.com/angular/angular.js/blob/master /auto/injectorSpec.js

假設你的函數名是foo

是否有可能將Javascript函數的所有參數都寫入接受?

arguments[0]arguments[foo.length-1]

如果沒有,是否可以獲得參數的數量?

foo.length會起作用

只檢查所需的字符。 使用func.toString()。正則表達式檢查全長。如果函數是500行代碼的類...

function getParams(func){
    var str=func.toString();
    var len = str.indexOf("(");
    return str.substr(len+1,str.indexOf(")")-len -1).replace(/ /g,"").split(',')
}

HBP的答案是大多數人都在尋找的,但如果你是定義函數的人,你也可以為函數對象分配一個屬性。 例如,

a.arguments = ['foo', 'bar', 'baz']
function a(foo, bar, baz) {
  // do stuff
}

這是更清楚的,但你必須寫兩次你的論點。

現在,當你在函數體外說我只能想象你想知道參數的名稱是什么? 因為就值而言,你已經知道你傳遞了什么參數。 其他答案說你可以得到函數的長度,它是顯式聲明的參數數量。 現在,如果你想知道函數之外的名字toString hack怎么樣?

考慮

function f(oh, hi, there) {
    return hi + there / oh;
}

然后

alert(f);

你看到了什么? 直接,只是正則表達出來! 好的,抱歉要提起這件事。 也許它不是標准的ECMAScript,但它,呃,適用於Chrome ....

 args = f => f.toString () .replace( /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg,'') .replace(/(\\r\\n\\t|\\n|\\r\\t)/gm,"") .trim() .match (/(?:\\w*?\\s?function\\*?\\s?\\*?\\s*\\w*)?\\s*(?:\\((.*?)\\)|([^\\s]+))/) .slice (1,3) .join ('').replace(/\\s/g, ''). split (/\\s*,\\s*/); /*Test*/ console.log(args((a,b)=>a+b)); console.log(args(function(c,d){return c+d;})); console.log(args(async function(a,b,c){/**/})); console.log(args(function* (a,b,c,d){/**/})); console.log(args(function name(s1,s2){})); console.log(args(function name(/*comment 1*/ s3/*comment2*/,s4// ){})); console.log(args(async function* name(/*comment1*/ s5/*comment2*/,s6){})); console.log(args(async function * name(/*comment1*/ s7/*comment2*/,s8){})); console.log(args(async function *name(/*comment1*/ s9/*comment2*/,s10){})); 

JavaScript是ECMAScript的一種方言,根據ECMAScript標准,一個函數也是一個對象,當一個函數被調用時,函數可以訪問參數對象,這個參數是類似於數組的對象,它有長度屬性,所以你可以使用參數.length遍歷傳遞給此函數的所有參數。 有關詳細信息,請訪問http://interglacial.com/javascript_spec/a-13.html#a-13.2.1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM