@aivazovski

Лексическое окружение, контекст вызова. Почему это разные понятия?

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

Почему эти 2е вещи разделены ? Ну т.е. в JS всё объекты, и даже функции. Но у функцию нельзя указать в this. Хотя, по идее, через this можно получить параметры объекта (они же аргументы функции), которые доступны через лексическое окружение. В чём разница, кроме того что лексическое окружение "для функций", а this "для объектов" ? Тут есть что то основополагающее, что я не могу уловить.
  • Вопрос задан
  • 2344 просмотра
Решения вопроса 1
AngReload
@AngReload
Кратко о себе
// лексическое окружение это все переменные
// которые доступны в момент создания функции
const lexEnv = 42
const lexEnv2 = 32
const lexEnv3 = 16
const lexEnv4 = 4

// создаём функцию
function fn() {
  console.log([
    lexEnv, // эта переменная взята из окружения
    this,
    this.field + lexEnv
  ])
}

const obj1 = {
  field: 8,
  myFn: fn
}

obj1.myFn() // здесь this становится равен obj1, this.field === 8


// пример другого this
let obj2 = {
  field: 100
}
obj2.myFn2 = obj1.myFn
// если мы использовать функцию как метод другого объекта
obj2.myFn2() // здесь this становится равен obj2, this.field === 100
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
sergiks
@sergiks Куратор тега JavaScript
♬♬
Лекс. окружение – это переменные, которые определены и "видны" функции.
Контекст – это this.
function outer() {
  var a = 1; // переменная в лексическом окружении ф-ии inner()
             // внутри inner() можно использовать значение a
  return function inner() {
    console.log("a == ", a, "this == ", this);
  }
}

var f1 = outer(); // f1 - функция
f1(); // a == 1, this == window или self

var f2 = f1.bind({title: "Ololo"}); // f2 - новая функция
f2(); // a == 1, this.title == "Ololo"
Ответ написан
@undefined_title
Лексическое окружение - это все локальные переменные функции, Определяется во время создания функции, есть еще понятие скоуп - это переменные которые доступны из другой функции и они берутся из замыкания.
Контекст вызова - это ссылка на объект из которого вызывается метод, это определяется во время вызова( кроме es6 arrow), то есть `a.b.c.call()` a.b.c будет контекстом вызова для метода call.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы