Можно ли создавать функции во время выполнения в Javascript?

В статье Википедии о первоклассных гражданах говорится, что «некоторые авторы» считают, что функции являются первоклассными гражданами только на языке, если язык поддерживает их создание во время выполнения. Эта статья, написанный Джеймсом Когланом, прямо называет функции первоклассными гражданами - я не знаю, осведомлен ли он о споре по поводу критериев первоклассности.

Вот мои вопросы:

  1. Являются ли процедуры JavaScript первоклассными гражданами при использовании дополнительных критериев «создание во время выполнения»?

Стоит упомянуть, что, исходя из более общих критериев (применимых к другим объектам в целом), функции JavaScript, очевидно, являются первоклассными гражданами, а именно, они могут передаваться как переменные; поэтому я считаю, что упомянутые выше критерии добавляют интересную динамику - или, по крайней мере, уточняющую динамику - к беседе, которая, как пишет один пользователь, не является "произвольной".

  1. Если да, то как выглядит создание функции во время выполнения в JavaScript (это то, что мы называем обещаниями, обратными вызовами, анонимностью и т. Д.)?
  2. Если нет, то как выглядит создание функции во время выполнения на другом языке?

person Thomas    schedule 11.02.2015    source источник
comment
Этот вопрос SO очень похож на ваш вопрос.   -  person AWolf    schedule 12.02.2015
comment
@ColeJohnson, это технически неверно. Прочтите о споре о первоклассных функциях гражданина: programmers.stackexchange.com/questions/39742/ (например; есть богатство больше в интернете)   -  person Thomas    schedule 12.02.2015


Ответы (2)


Функции можно создавать динамически с помощью Function constructor

var adder = new Function('a', 'b', 'return a + b');

adder(3, 4); // returns 7

Более подробно, это можно было бы использовать для применения произвольного бинарного оператора:

function make_binary_fun(operator) {
    return new Function('a', 'b', 'return a ' + operator ' b');
}
var adder = make_binary_fun('+');
var multiplier = make_binary_fun('*');
person Barmar    schedule 11.02.2015
comment
Верно, но редко используется в реальной жизни; пример в ответе Сэмюэля Эдвина Уорда лучше, потому что он демонстрирует, что функции являются первоклассными через обычные языковые конструкции, используемые в повседневном JavaScript, а не через конструкцию, которая редко используется и является довольно злой (по тем же причинам, что и eval). - person Mark Amery; 12.02.2015
comment
Вопрос не совсем ясен в том, что это значит. Этот ответ заключается в создании новых закрытий одной и той же функции, а не новых функций. Я не думаю, что вопрос касался того, что используется в реальной жизни, а просто общий вопрос о дизайне и возможностях языка. - person Barmar; 12.02.2015
comment
Это каррирование и технически создание новой функции каждый раз, когда вы ее вызываете. Не уверен, почему это тоже неверный ответ. (Я поддержал оба, кстати) - person Marc; 12.02.2015
comment
Назвать это новым закрытием той же функции не соответствует какой-либо терминологии, с которой я знаком из мира JavaScript. В терминологии JS каждая вещь, возвращаемая из makeIncrementer Самуэля, является Function (возвращенные объекты имеют Function в качестве своего .constructor свойства), и они не равны. Я не вижу разумной точки зрения, с которой ответ Самуэля был бы менее верным, чем этот. - person Mark Amery; 12.02.2015
comment
См. Мой обновленный ответ о вещах, которые было бы сложно сделать одним закрытием. - person Barmar; 12.02.2015
comment
Я не уверен, что в JavaScript действительно есть различие между новым закрытием той же функции и новой функцией. Насколько мне известно, все они просто отдельные экземпляры Function. - person Samuel Edwin Ward; 12.02.2015
comment
@Barmar Если бы вы действительно хотели сделать свой второй пример способом замыкания, вы бы просто использовали вызов eval() внутри выражения функции. И если мы собираемся говорить об ограничениях двух подходов, способ конструктора Function не разрешает вам вообще никакого доступа к локальным переменным функции, из которой создается new Function, что делает этот метод строго менее мощным. чем метод закрытия, и с его помощью многие полезные вещи становятся невозможными. - person Mark Amery; 12.02.2015
comment
Я принимаю этот ответ из-за добавления второго примера. - person Thomas; 12.02.2015
comment
Как я уже сказал в комментариях, это действительно зависит от того, какую проблему вы пытаетесь решить. Непонятно даже, в чем суть вопроса, похоже, просто о том, соответствует ли он какому-то произвольному определению, это не влияет на фактическое программирование. - person Barmar; 12.02.2015
comment
@Barmar, суть вопроса в том, предоставляет ли JavaScript возможность создавать функции во время выполнения, на что вы ответили. Я не уверен, как это не влияет на программирование; тем не менее, этот вопрос информирует участников мета-разговора о том, является ли JavaScript функциональным языком программирования по своей сути. - person Thomas; 12.02.2015

Вот пример функции, которая создает функцию во время выполнения в JavaScript:

function makeIncrementer(value) {
    return function(x) {
        return x+value;
    }
}

Он принимает значение и возвращает функцию, которая добавляет это значение к его входным данным.

Вот несколько примеров того, как это можно назвать:

var f = makeIncrementer(5);
f(2); // 7
f.call(null, 3); // 8
f.apply(null, [4]); /// 9
var object = {};
object.increment = f;
object.increment(5); // 10
person Samuel Edwin Ward    schedule 11.02.2015
comment
@SamuelEdwinWard просто хочет вслух признать ваш первый ответ, а также ответ, который лучше всего подходит для вопроса. Честно говоря, выбор между вашим и другим был произвольным. Спасибо за время, которое вы вложили в ответ. - person Thomas; 12.02.2015