0

Background

I am learning how the arguments object works inside a function. I noticed that in theory, this object will have all the arguments passed to the function.

In practice I have quite different results.

Code

The following code is a test function, that prints the arguments it receives:

function test(myArgs){
    console.log(`myArgs: ${myArgs}`);
    console.log(`arguments obj: ${JSON.stringify(arguments)}`);
    console.log(`arguments array ${JSON.stringify(Array.from(arguments))}`);
}

the first line prints myArgs and the other two print the arguments object in a couple different ways.

Executing the function with something simple it works:

test("hello", 56, 60, 5);

myArgs: hello
arguments obj: {"0":"hello","1":56,"2":60,"3":5}
arguments array ["hello",56,60,5]

Problem

The problem comes when I pass a function as one of the arguments, like, lets say, a callback:

test("hello", () => console.log("HelloWorld"), 60, 5);

myArgs: hello
arguments obj: {"0":"hello","2":60,"3":5}
arguments array ["hello",null,60,5]

This is quite unexpected ...

Code

Following is a snippet that exemplifies this behavior:

    function test(myArgs){
     console.log(`myArgs: ${myArgs}`);
     console.log(`arguments obj: ${JSON.stringify(arguments)}`);
     console.log(`arguments array ${JSON.stringify(Array.from(arguments))}`);
    }

test("hello", 56, 60, 5);
test("hello", () => console.log("HelloWorld"), 60, 5);

Questions

  1. Why doesn't this work?
  2. How can I access a function if I have multiple arguments ?
Flame_Phoenix
  • 16,489
  • 37
  • 131
  • 266
  • 1
    JSON cannot contain functions as values, so you end up with `null`. – Pointy Jun 21 '17 at 14:21
  • 2
    Also note that the `arguments` object is more or less deprecated in modern JavaScript. – Pointy Jun 21 '17 at 14:21
  • 1
    console.log doesn't require you to JSON.stringify objects. It'll stringify them for you in a human readable way – SethWhite Jun 21 '17 at 14:21
  • 1
    To add to Pointy's comment, the spread operator is now the accepted way to access variadic parameters. (...myArgs) => console.log(...myArgs); – SethWhite Jun 21 '17 at 14:23
  • 1
    @Pointy actually, I think `JSON.stringify(fn)` returns `undefined` but in the context of a container, that gets converted to `null`. – canon Jun 21 '17 at 14:27
  • Possible duplicate of [json.stringify does not process object methods](https://stackoverflow.com/questions/18089033/json-stringify-does-not-process-object-methods) – Nope Jun 21 '17 at 14:28
  • @canon sure, that's possible; the point is that it's not the function :) – Pointy Jun 21 '17 at 14:31
  • When I first created this post my focus was on Functions, not objects. So I object to it being a dup. Thanks for answer and directions ! – Flame_Phoenix Jun 21 '17 at 14:44

1 Answers1

3

By default, JSON.stringify() doesn't serialize functions.

... but it can. Provide a custom replacer callback and handle serialization of functions yourself:

var values = [1, false, {foo:2}, function bar() {}];

console.log(JSON.stringify(values, function(key, value) {
  if ("function" === typeof value) {
    return value.toString();
  }
  return value;
}));

See Function.prototype.toString() and JSON.stringify(value, replacer).

canon
  • 40,609
  • 10
  • 73
  • 97