Аргументы функции JavaScript - PullRequest
2 голосов
/ 28 июня 2011

Я пытаюсь создать функцию, которая десериализует объект JSON и создает некоторые функции, но я хочу иметь возможность указывать переменный набор аргументов.

Например, в JSON я хочу указать что-то вроде:

{
  "handler" :
  {
    "args" : ["evt","value"],
    "content" : "console.log(value);"
  }
}

И когда я проанализирую объект, я сделаю что-то вроде:

var myFunction = new Function(handler.args,handler.content);

Но проблема в том, что каждый аргумент должен быть строкой n , за которой следует содержание функции в качестве последнего аргумента. Есть ли простой способ указать n количество аргументов в new Function()?

Ответы [ 4 ]

5 голосов
/ 28 июня 2011

Для решения технической проблемы: Вы можете использовать apply [документы] .

handler.args.push(handler.content);
var myFunction = Function.apply(null, handler.args);

Однако вопрос в том, почему вы делаете что-то подобное? Каков контекст? Спонтанно я бы сказал, что вы должны рассмотреть другое решение для любой проблемы, которую вы пытаетесь решить;)

1 голос
/ 28 июня 2011

Согласно MDN

Параметры

arg1, arg2, ... argN

Имена, которые будут использоваться функцией в качестве имен формальных аргументов. Каждый должен быть строка, которая соответствует действительному Идентификатор JavaScript или список такие строки разделяются запятой; например "x", "theValue" или "a, b" .

Таким образом, список аргументов может состоять из одной или нескольких строк, разделенных запятыми, или только из одной строки, в которой каждый идентификатор разделен запятыми.

Также с

['evt', 'value'].toString() == 'evt,value'

Простая передача массива handler.args в качестве первого аргумента конструктору new Function должна работать точно так, как вы хотите

new Function(handler.args, handler.content);

Внутренне, new Function преобразует каждый аргумент в строку, если он еще не один. Так что, возможно, что-то подобное будет работать

new Function({ toString: function() { return 'a,b,c' } }, 'return a+b+c');

Не то чтобы я предлагал вам сделать что-нибудь глупое, как это.

Это работает во всех браузерах, которые я пробовал, включая IE

1 голос
/ 28 июня 2011

Я думаю, что самым простым способом было бы объединить 2 свойства.Затем используйте apply для построения функции.

var x = {
  "handler" :
  {
    "constructorArgs" : [
        "evt",
        "value",
        "alert(value);"
    ]
  }
};

var f = Function.apply(undefined, x.handler.constructorArgs);
f(1, 2);

Чтобы сохранить ее сходство, вы можете использовать Array.prototype.concat.

var x = {
  "handler" :
  {
      args: [ "evt", "value" ],
      content : "alert(value);"
  }
};

var f = Function.apply(undefined, x.handler.args.concat(x.handler.content));
f(1, 2);
0 голосов
/ 28 июня 2011

Разве вы не можете заставить тело своих функций работать со свойством arguments?

http://jsfiddle.net/9XcEb/

var add = new Function(
    "var total=0;"+
    "for (var i=0; i < arguments.length; i++) {"+
       "total+=arguments[i]"+
    "};"+
    " return total"
);

alert(add(3,4,5,6));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...