Hướng dẫn get parameter name javascript
The following function will return an array of the parameter names of any function passed in. Show
Example usage:
Edit: With the invent of ES6 this function can be tripped up by default parameters. Here is a quick hack which should work in most cases:
I say most cases because there are some things that will trip it up
Edit: I also note vikasde wants the parameter values in an array also. This is already provided in a local variable named arguments. excerpt from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments: The arguments object is not an Array. It is similar to an Array, but does not have any Array properties except length. For example, it does not have the pop method. However it can be converted to a real Array:
If Array generics are available, one can use the following instead:
answered Mar 29, 2012 at 11:30
Jack AllanJack Allan 14k11 gold badges43 silver badges55 bronze badges 26
Below is the code taken from AngularJS which uses the technique for its dependency injection mechanism. And here is an explanation of it taken from http://docs.angularjs.org/tutorial/step_05
answered Aug 24, 2012 at 11:39
LambderLambder 2,8621 gold badge25 silver badges20 bronze badges 7 Here is an updated solution that attempts to address all the edge cases mentioned above in a compact way:
Abbreviated test output (full test cases are attached below):
answered Jul 2, 2015 at 21:28
humbletimhumbletim 1,06811 silver badges10 bronze badges 9 Solution that is less error prone to spaces and comments would be:
answered Feb 2, 2013 at 8:26
buberssonbubersson 7591 gold badge6 silver badges12 bronze badges 1 A lot of the answers on here use regexes, this is fine but it doesn't handle new additions to the language too well (like arrow functions and classes). Also of note is that if you use any of these functions on minified code it's going to go 🔥. It will use whatever the minified name is. Angular gets around this by allowing you to pass in an ordered array of strings that matches the order of the arguments when registering them with the DI container. So on with the solution:
This handles the original parse issue and a few more function types (e.g. arrow functions). Here's an idea of what it can and can't handle as is:
Depending on what you want to use it for ES6 Proxies and destructuring may be your best bet. For example if you wanted to use it for dependency injection (using the names of the params) then you can do it as follows:
It's not the most advanced resolver out there but it gives an idea of how you can use a Proxy to handle it if you want to use args parser for simple DI. There is however one slight caveat in this approach. We need to use destructuring assignments instead of normal params. When we pass in the injector proxy the destructuring is the same as calling the getter on the object.
This outputs the following:
Its wired up the entire application. The best bit is that the app is easy to test (you can just instantiate each class and pass in mocks/stubs/etc). Also if you need to swap out implementations, you can do that from a single place. All this is possible because of JS Proxy objects. Note: There is a lot of work that would need to be done to this before it would be ready for production use but it does give an idea of what it would look like. It's a bit late in the answer but it may help others who are thinking of the same thing. 👍 answered Jan 7, 2017 at 18:57
James DrewJames Drew 5885 silver badges9 bronze badges 0 I know this is an old question, but beginners have been copypasting solutions that extract parameter names from the string representation of a function as if this was good practice in any code. Most of the time, this just hides a flaw in the logic. Writing parameter names in the parentheses of a function declaration can be seen as a shorthand syntax for variable creation. This:
...is akin to this:
The variables themselves are stored in the function's scope, not as properties in an object. Just like you can't manipulate the name of a variable with code, there is no way to retrieve the name of a parameter as it is not a string, and it could be eliminated during JIT compilation. I always thought of the string representation of a function as a tool for debugging purposes, especially because of this Here's an even worse and more common situation. If a function has more than 3 or 4 arguments, it might be logical to pass it an object instead, which is easier to work with.
In this case, the function itself will be able to read through the object it receives and look for its properties and get both their names and values, but trying to parse the string representation of the function would only give you "obj" for parameters, which isn't useful at all. answered Aug 20, 2015 at 2:19
DominoDomino 5,91134 silver badges57 bronze badges 6 I have read most of the answers here, and I would like to add my one-liner.
or
or for a one-liner function in ECMA6
__ Let's say you have a function
The below code will return That code will also work with the setup of a function that Camilo Martin gave:
Also with Bubersson's comment on Jack Allan's answer:
__ Explanationnew RegExp('(?:'+Function.name+'\\s*|^)\\s*\\((.*?)\\)')This creates a
Regular Expression with the Example If the function name is "foo" ( Function.toString().replace(/\n/g, '')Then it converts the entire function into a string, and removes all newlines. Removing newlines helps with the function setup Camilo Martin gave. .exec(...)[1]This is the .replace(/\/\*.*?\*\//g, '').replace(/ /g, '')This will remove every comment inside This also now supports reading and understanding arrow ( The change was from If you want to make all the parameters into an Array instead of a String separated by commas, at the end just add
answered Aug 31, 2016 at 15:42
ZomoXYZZomoXYZ 1,62418 silver badges43 bronze badges 5 Since JavaScript is a scripting language, I feel that its introspection should support getting function parameter names. Punting on that functionality is a violation of first principles, so I decided to explore the issue further. That led me to this question but no built-in solutions. Which led me to
this answer which explains that
Time to roll up our sleeves and get to work: ⭐ Retrieving function parameters requires a parser because complex expressions like I tried the babylon and esprima parsers but unfortunately they can't parse standalone anonymous functions, as pointed out in Mateusz Charytoniuk's answer. I figured out another workaround though by surrounding the code in parentheses, so as not to change the logic:
The newlines prevent issues with ⭐ If a parser is not available, the next-best option is to use a tried-and-true technique like Angular.js's dependency injector regular expressions. I combined a functional version of
Lambder's answer with humbletim's answer and added an optional Here are two solutions I put together. Note that these have no logic to detect whether a function has valid syntax, they only extract the arguments. This is generally ok
since we usually pass parsed functions to I will try to curate these solutions as best I can, but without effort from the JavaScript maintainers, this will remain an open problem. Node.js version (not runnable until StackOverflow supports Node.js):
Full working example: https://repl.it/repls/SandybrownPhonyAngles Browser version (note that it stops at the first complex default value):
Full working example: https://repl.it/repls/StupendousShowyOffices answered Mar 28, 2018 at 21:18
Zack MorrisZack Morris 4,5912 gold badges52 silver badges80 bronze badges 4
=> [ "a", "b", "c" ] answered Aug 2, 2013 at 7:19
WillWill 2,4142 gold badges16 silver badges14 bronze badges 1 You can also use "esprima" parser to avoid many issues with comments, whitespace and other things inside parameters list.
It works even with code like this:
answered Feb 26, 2014 at 13:39
The proper way to do this is to use a JS parser. Here is an example using acorn.
The code here finds the names of the three (formal) parameters of the function answered Jul 1, 2018 at 22:33
Itay MamanItay Maman 29.6k10 gold badges84 silver badges115 bronze badges 1 I've tried doing this before, but never found a praticial way to get it done. I ended up passing in an object instead and then looping through it.
answered Jun 17, 2009 at 16:00
hugowarehugoware 34.8k24 gold badges60 silver badges70 bronze badges 2 I don't know if this solution suits your problem, but it lets you redefine whatever function you want, without having to change code that uses it. Existing calls will use positioned params, while the function implementation may use "named params" (a single hash param). I thought that you will anyway modify existing function definitions so, why not having a factory function that makes just what you want:
Hope it helps. answered Jun 17, 2009 at 16:50
Ionuț G. StanIonuț G. Stan 171k18 gold badges187 silver badges199 bronze badges Taking the answer from @jack-allan I modified the function slightly to allow ES6 default properties such as:
to still return
answered Mar 18, 2015 at 13:46
thelastshadowthelastshadow 3,2653 gold badges34 silver badges35 bronze badges 1 As this has not yet been mentioned, if you are using Typescript you can emit meta-data when using Decorators which will allow you to get the parameter types. Metadata will only be emitted if the class/function/prop has a decorator on it. This feature can be enabled by setting emitDecoratorMetadata to true inside tsconfig.json
As the metadata is still an early proposal the reflect-metadata package must be installed or Reflect.getMetadata will not be defined.
You can use it as follows:
In newer versions of Angular for instance this is used to determine what to inject -> https://stackoverflow.com/a/53041387/1087372 answered Oct 2, 2020 at 9:41
SanBenSanBen 1,98921 silver badges31 bronze badges 3 I don't know how to get a list of the parameters but you can do this to get how many it expects. Note this only counts arguments without a default value in the signature:
Flimm 122k39 gold badges235 silver badges247 bronze badges answered Jun 17, 2009 at 16:00
Ólafur WaageÓlafur Waage 67.3k19 gold badges141 silver badges194 bronze badges 1
answered Jan 28, 2013 at 3:18
Paul LanPaul Lan 6562 gold badges9 silver badges12 bronze badges The answer to this requires 3 steps:
The code will be like this
and the logged object will be
And here's a working example https://tonicdev.com/5763eb77a945f41300f62a79/5763eb77a945f41300f62a7a answered Jun 17, 2016 at 12:42
gafigafi 11.5k2 gold badges29 silver badges31 bronze badges
falsarella 12.1k9 gold badges69 silver badges113 bronze badges answered Nov 21, 2013 at 18:32
Wow so many answers already.. Im pretty sure this gets buried. Even so I figured this might be useful for some. I wasn't fully satisfied with the chosen answers as in ES6 it doesn't work well with default values. And it also does not provide the default value information. I also wanted a lightweight function that does not depend on an external lib. This function is very useful for debugging purposes, for example: logging called function with its params, default param values and arguments. I spent some time on this yesterday, cracking the right RegExp to solve this issue and this is what I came up with. It works very well and I'm very pleased with the outcome:
As you can tell some of the parameter names disappear because the Babel transpiler removes them from the function. If you would run this in the latest NodeJS it works as expected (The commented results are from NodeJS). Another note, as stated in the comment is that is does not work with inlined arrow functions as a default value. This simply makes it far to complex to extract the values using a RegExp. Please let me know if this was useful for you! Would love to hear some feedback! answered Dec 25, 2016 at 16:16
SnailCrusherSnailCrusher 1,24411 silver badges10 bronze badges How I typically do it:
You can even ref the args by the functions name like:
Hope this helps! answered Aug 20, 2012 at 1:17
CodyCody 9,4394 gold badges59 silver badges45 bronze badges 2 I'll give you a short example below:
answered May 19, 2017 at 7:29
2 This package uses recast in order to create an AST and then the parameter names are gathered from their, this allows it to support pattern matching, default arguments, arrow functions and other ES6 features. https://www.npmjs.com/package/es-arguments answered Oct 14, 2017 at 17:31
I have modified the version taken from AngularJS that
implements a dependency injection mechanism to work without Angular. I have also updated the
answered Nov 29, 2017 at 23:28
loretoparisiloretoparisi 14.8k11 gold badges93 silver badges132 bronze badges You can access the argument values passed to a function using the "arguments" property.
answered Jun 17, 2009 at 18:11
letronjeletronje 8,8119 gold badges43 silver badges53 bronze badges 2 It's pretty easy. At the first there is a deprecated https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee All of them going to call toString and replace with re so we can create a helper:
Some examples:
Enjoy with JS! UPD: Jack Allan was provided a little bit better solution actually. GJ Jack! answered Feb 1, 2013 at 23:30
1 Whatever the solution, it must not break on wierd functions, whose
Also, why use complex regular expressions? This can be done like:
This works everywhere with every function, and the only regex is whitespace removal that doesn't even process the whole string due to the answered May 19, 2015 at 10:02
Camilo MartinCamilo Martin 36.3k20 gold badges109 silver badges153 bronze badges Ok so an old question with plenty of adequate answers. here is my offering that does not use regex, except for the menial task of stripping whitespace . (I should note that the "strips_comments" function actually spaces them out, rather than physically remove them. that's because i use it elsewhere and for various reasons need the locations of the original non comment tokens to stay intact) It's a fairly lengthy block of code as this pasting includes a mini test framework.
answered Aug 3, 2016 at 10:35
unsynchronizedunsynchronized 4,7692 gold badges30 silver badges41 bronze badges Here's one way:
Note: This only works on browsers that support answered Jun 17, 2009 at 19:14
Ates GoralAtes Goral 134k26 gold badges135 silver badges189 bronze badges 5 Note: if you want to use ES6 parameter destructuring with the top solution add the following line.
answered Jan 5, 2018 at 22:47
|