Книга: Выразительный JavaScript

Функции

Функции

Язык программирования без функций – плохой язык.

К счастью, несложно добавить конструкцию fun, которая расценивает последний аргумент как тело функции, а все предыдущие – имена аргументов функции.

specialForms["fun"] = function(args, env) {
  if (!args.length)
    throw new SyntaxError("Функции нужно тело");
  function name(expr) {
    if (expr.type != "word")
      throw new SyntaxError("Имена аргументов должны быть типа word");
    return expr.name;
  }
  var argNames = args.slice(0, args.length - 1).map(name);
  var body = args[args.length - 1];
  return function() {
    if (arguments.length != argNames.length)
      throw new TypeError("Неверное количество аргументов");
    var localEnv = Object.create(env);
    for (var i = 0; i < arguments.length; i++)
      localEnv[argNames[i]] = arguments[i];
    return evaluate(body, localEnv);
  };
};

У функций в Egg своё локальное окружение, как и в JavaScript. Мы используем Object.create для создания нового объекта, имеющего доступ к переменным во внешнем окружении (своего прототипа), но он также может содержать новые переменные, не меняя внешней области видимости.

Функция, созданная формой fun, создаёт своё локальное окружение и добавляет к нему переменные-аргументы. Затем она интерпретирует тело в этом окружении и возвращает результат.

run("do(define(plusOne, fun(a, +(a, 1))),",
    "   print(plusOne(10)))");
// ? 11
run("do(define(pow, fun(base, exp,",
    "     if(==(exp, 0),",
    "        1,",
    "        *(base, pow(base, -(exp, 1)))))),",
    "   print(pow(2, 10)))");
// ? 1024

Оглавление книги


Генерация: 0.046. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз