Можно ли отразить аргументы функции Javascript?
Можно ли получить все аргументы, которые написана для принятия функции Javascript? (Я знаю, что все аргументы функции Javascript являются "необязательными")? Если нет, возможно ли получить количество аргументов? Например, в PHP можно использовать:
$class = new ReflectionClass('classNameHere');
$methods = $class->getMethods();
foreach ($methods as $method) {
print_r($method->getParameters());
}
... или что-то в этом роде, я некоторое время не касался PHP, поэтому приведенный выше пример может быть неверным.
Заранее спасибо!
РЕДАКТИРОВАТЬ: К сожалению, я должен иметь возможность получить аргументы за пределами тела функции... Извините за отсутствие разъяснений, но спасибо за текущие ответы!
7 ответов
Предположим, что ваша функция называется foo
Можно ли получить все аргументы, которые написана для принятия функции Javascript?
arguments[0]
в arguments[foo.length-1]
Если нет, возможно ли получить количество аргументов?
foo.length
должно сработать
Эта новая версия также поддерживает функции жирных стрелок...
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*/);
Аргументы будут массивом имен аргументов теста, т. е. ['a', 'b', 'c']
Значение args будет массивом имен параметров, если ftest
это функция. Массив будет пустым, если ftest
не имеет параметров. Значение args
будет null
если ftest
не совпадает с регулярным выражением, т. е. не является функцией.
Можно получить все формальные параметры имени 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 и реализован в функции аннотирования. (см. https://github.com/angular/angular.js/blob/master/src/auto/injector.js и соответствующий модульный тест в https://github.com/angular/angular.js/blob/master/auto/injectorSpec.js)
Проверьте только необходимые символы. с func.toString().regex вы проверили full length.so, если функция класса с 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
взломать?
Рассматривать
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 для получения более подробной информации.