> For the complete documentation index, see [llms.txt](https://strctr.gitbook.io/programming/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://strctr.gitbook.io/programming/01-languages/javascript/01-language/a-core/a1-javascript-execution/05-lexical-closure.md).

# 05. Lexical Closure

**Замыкание** (Closure) или более полно — **лексическое замыкание** (Lexical closure) — это совокупность функции и данных того контекста (окружения), в котором эта функция создана.

If a function leaves the scope in which it was created, it stays connected to the variables of that scope where function was declared (and of the surrounding scopes). A **closure** is a function plus the connection to the scope in which the function was created:

```javascript
const threshold = 100;

function createInc(startValue) {
  return function(step) {
    startValue += step;
    if (startValue > threshold) {
      return threshold;
    }
    return startValue;
  };
}

const inc = createInc(5);
inc(1); // => 6
inc(2); // => 8
```

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

Как пример, при создании нового объекта/класса есть смысл помещать все методы в прототип этого объекта, а не описывать их в тексте конструктора. Дело в том, что если сделать по-другому, то при каждом создании объекта для него будет создан свой экземпляр каждого из методов, вместо того, чтобы наследовать их из прототипа.

```javascript
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}
```

Поскольку вышеприведенный код никак не использует преимущества замыканий, его можно переписать следующим образом:

```javascript
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};
```
