3

Is it possible to access arguments name strings?!

function myFunction (a, b, c, d, e, f) {
    var obj = [];
    [].forEach.call(arguments, function(arg) {
        obj.push({
            // question is how to get variable name here?
            name: "a",// "a", "b", "c", "d", "e", "f"
            value: arg, //a, b, c, ,d, e, f
        })
    });
 return obj;
}

myFunction(1,2,3,4,5,6); // return [{name: "a", value: 1}, {name: "b", value: 2}...]

Note: I know using arguments is not a good practice. I want to know if this even possible or not?

Mohsen
  • 64,437
  • 34
  • 159
  • 186
  • How could `myFunction` return anything if it doesn't have a return statement? – David G Jun 25 '12 at 17:28
  • I have yet to find a basic way to retrieve the names of the argument variables. Values is cake, names not so much. – j08691 Jun 25 '12 at 17:36

6 Answers6

6

You could try something like this:

function myFunction (a, blabla, c, somethingElse, e, f) {
    var obj = [];
    //'(a, b, c, d, e, f)' 
    var tmp = arguments.callee.toString().match(/\(.*?\)/)[0];
    //["a", "b", "c", "d", "e", "f"] 
    var argumentNames = tmp.replace(/[()\s]/g,'').split(',');

    [].splice.call(arguments,0).forEach(function(arg,i) {
        obj.push({
            // question is how to get variable name here?
            name: argumentNames[i],
            value: arg
        })
    });
    return obj;
}

console.log(JSON.stringify(myFunction(1, 2, 3, 4, 5, 6)));
//Output-> [{"name":"a","value":1},{"name":"blabla","value":2},
//          {"name":"c","value":3},{"name":"somethingElse","value":4},
//          {"name":"e","value":5},{"name":"f","value":6}]

DEMO

Engineer
  • 47,849
  • 12
  • 88
  • 91
  • Nice hack. `callee` is what I never thought about. – Mohsen Jun 25 '12 at 17:57
  • Yep, I agree. But consider reading https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee too – KooiInc Jun 25 '12 at 18:04
  • @KooiInc Yes, `callee` is forbidden *only in strict mode*, but not in entire javascript at all. – Engineer Jun 25 '12 at 18:09
  • +1 For finding a creative solution, though I'd agree that `.callee` shouldn't be used when you could use the function name. –  Jun 25 '12 at 18:13
  • @amnotiam I have tried to not hardcode the function's name, but sure `arguments.callee` can be replaced by `myFunction`. – Engineer Jun 25 '12 at 18:15
  • 1
    @Engineer, it's not forbidden in non strict js, but it *is* deprecated for a number of reasons, very well explained here: http://stackoverflow.com/questions/103598/why-was-the-arguments-callee-caller-property-deprecated-in-javascript. – KooiInc Jun 25 '12 at 18:19
  • @KooiInc But who was talking about `argument.callee.caller` ?? `arguments.callee` was, what I meant. – Engineer Jun 25 '12 at 18:22
  • @Engineer: the linked SO-answer is about both `callee` and `caller`, if I understood right – KooiInc Jun 25 '12 at 18:25
  • @KooiInc See the `RobG`'s comment. And it silly to think, that `argument.callee` is added *only* for supporting `inline anonymous function recursion`. The core advantage of `arguments.callee`, is making things *generic*. If you have enough time and interest, you might look at [goog.base](https://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js) lib, especially `inherits` and `base` methods. It will be very interesting to alter `arguments.callee.caller` concept in `goog.base` method. What will you do?!! Ugly hardcoding?!!! – Engineer Jun 27 '12 at 19:39
  • @Engineer: RobG where? Anyway, don't get all worked up on it. I justed added the comment as a side note. Feel free to use and/or advocate the use of `arguments.callee[.caller]`. I'll give you one more link for further reading: http://bonsaiden.github.com/JavaScript-Garden/#function.arguments. Let me repeat: I am really not forbidding anyone anything. – KooiInc Jun 27 '12 at 20:17
  • @KooiInc thanks for the link.But I'm not changing my opinion related to `argument.callee`. You might agree, that in the most cases such performance problems(caused by `argument.callee`) will not be 'visible',but on the other hand developer should write *easy-maintainable* code, *generic* code, *non-hardcode*,which is more important for the developer. Cheers – Engineer Jun 27 '12 at 21:21
2

Are the function parameter names definied in the function definition, as you've written above? If so, you can just create an array in the function:

function myFunction(a,b,c,d,e,f) {
  var argNames = ['a','b','c','d','e','f'];
  ...
}

arguments will only ever contain a simple array of the arguments passed to the function. There is no default mapping from arguments to parameter names. That I'm aware of anyway

jackwanders
  • 15,612
  • 3
  • 40
  • 40
  • Yes, but you don't have any choice in the matter. There's no practical way to access function parameter names. Maybe you can clarify the context in which you're attempting this; perhaps there is a better solution? – jackwanders Jun 25 '12 at 17:59
0

This works:

function myFunction( _obj ) {

    var obj = [],
        names = [],
        args = arguments,
        len = function(o) {
            var a = [];

            for (var i in o) a.push(i);

            return a;
        };

    for (var i in _obj) names.push( i );

    [].forEach.call( len(_obj), function(a, b) {
        obj.push({
            name: names[b],
            value: args[0][names[b]]
        });
    });

    return obj;

}

console.log( myFunction({
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: 5,
    f: 6
}));​​​​

Here is a DEMO

David G
  • 94,763
  • 41
  • 167
  • 253
  • He wants the name, so the first argument would have `name:"a"`, then `name:"b"`, `name:"c"`, etc. You're assigning `"a"` for every argument. –  Jun 25 '12 at 17:40
  • @Mohsen I was able to change it. Instead of inputting the arguments individually, I made it able to take an object literal instead. This version *does* work. – David G Jun 25 '12 at 18:00
  • Sorry, you have changed the question. – Mohsen Jun 25 '12 at 18:01
  • What do you mean, this functions as you have intended? – David G Jun 25 '12 at 18:04
0

For completeness: you can't use named parameters in javascript. If you want to use them (and thus be able to identify the parameter names), a workaround is to supply an object:

function myParams(params){
  var ret = [];
  for (var l in params){ 
   if (params.hasOwnProperty(l)){
    ret.push(l);
   }
  }
  return ret
}
myParams({a:1,b:2,c:3,d:null,e:null,f:null,g:11});
//=> [a,b,c,d,e,f,g]

See also...
And to be really complete: see this also

KooiInc
  • 119,216
  • 31
  • 141
  • 177
0

You can invoke toString on the function and then use some kind of RegEx to parse result.



    function someFunction(a,b,c){}
    var functionString = someFunction.toString(); //return "function someFunction(a,b,c){}"
    var args = functionString.match(/^function (?:.*?)\((.*?)\)/);
    if(args[1])
    {
        var argsNames = args[1].split(",");
    }


I've tested it on FF and Chrome.

cezarypiatek
  • 1,078
  • 11
  • 21
0

Since item.product_image2 is a URL string, you need to put it in quotes when you call changeImage inside parameter.

My Function Onclick

items+='<img src='+item.product_image1+' id="saleDetailDivGetImg">';
items+="<img src="+item.product_image2+"  onclick='changeImage(\""+item.product_image2+"\");'>";

My Function

<script type="text/javascript">
function changeImage(img)
 {
    document.getElementById("saleDetailDivGetImg").src=img;
    alert(img);
}
</script>