Что такое лексический охват?


682

Что представляет собой краткое введение в лексическое определение объема?


89
В подкасте 58 Джоэл поощряет подобные вопросы, поскольку он хочет, чтобы ТАК стал местом для ответов, даже если на них были даны ответы в других местах. Это правильный вопрос, хотя можно сказать, что он немного более вежлив.
Ральф М. Рикенбах

5
@rahul Я понимаю, что это старый вопрос. Но я уверен, что даже в 2009 году SO ожидал, что спрашивающие приложат некоторые основные усилия для его решения. В нынешнем виде это не показывает никаких усилий вообще. Может быть, поэтому за это проголосовали многие?
PP

13
Возможно, что спрашивающий не (или не очень) свободно говорил по-английски при написании этого вопроса
Martin

28
Вопрос вежливый, он просто говорит, что хочет. Вы можете ответить. Здесь нет необходимости в чрезмерной политичности.
Маркус Зибенихер

25
Я думаю, что такие вопросы великолепны, потому что они создают контент для SO. ИМО, кого волнует, если у вопроса нет усилий ... ответы будут отличными, и это то, что важно на этой доске объявлений.
Jwan622

Ответы:


687

Я понимаю их на примерах. :)

Во-первых, лексическая область (также называемая статической областью ) в C-подобном синтаксисе:

void fun()
{
    int x = 5;

    void fun2()
    {
        printf("%d", x);
    }
}

Каждый внутренний уровень может получить доступ к своим внешним уровням.

Есть еще один способ, называемый динамической областью действия, используемый первой реализацией Lisp , опять же в C-подобном синтаксисе:

void fun()
{
    printf("%d", x);
}

void dummy1()
{
    int x = 5;

    fun();
}

void dummy2()
{
    int x = 10;

    fun();
}

Здесь funможно либо доступ xв dummy1или dummy2, или любой xв любой функции, вызов funс xобъявленной в нем.

dummy1();

напечатает 5,

dummy2();

напечатает 10.

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

Я считаю, что статический обзор легче для глаз. В конце концов, большинство языков пошли по этому пути, даже Lisp (можно сделать и то, и другое?) Динамическая область видимости похожа на передачу ссылок на все переменные в вызываемую функцию.

В качестве примера того, почему компилятор не может определить внешнюю динамическую область действия функции, рассмотрим наш последний пример. Если мы напишем что-то вроде этого:

if(/* some condition */)
    dummy1();
else
    dummy2();

Цепочка вызовов зависит от условий выполнения. Если это правда, то цепочка вызовов выглядит так:

dummy1 --> fun()

Если условие ложно:

dummy2 --> fun()

Внешняя область действия funв обоих случаях - это вызывающая сторона плюс вызывающая сторона вызывающей стороны и т. Д. .

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


19
Я также хотел бы отметить очень простой для понимания урок, который я только что нашел. Пример Арака хорош, но может быть слишком коротким для того, кому нужно больше примеров (на самом деле, по сравнению с другими языками ..). Взглянуть. Важно , чтобы понять это , поскольку это ключевое слово приведет нас к пониманию лексической области. howtonode.org/what-is-this
CppLearner

9
Это хороший ответ. Но вопрос помечен как JavaScript. Поэтому я думаю, что это не должно быть отмечено как принятый ответ. Лексическая сфера конкретно в JS отличается
Boyang

6
Очень хороший ответ. Спасибо. @Boyang Я не согласен. Я не программист на Лиспе, но нашел пример с Лиспом полезным, так как это пример динамической области видимости, которого нет в JS.
dudewad

4
Первоначально я думал, что пример является допустимым кодом C и был сбит с толку, имелось ли динамическое определение области действия в C. Возможно, отказ от ответственности в конце можно перенести на перед примером кода?
Яншунь Тай

2
Это все еще очень полезный ответ, но я думаю, что @Boyang правильный. Этот ответ относится к «уровню», который больше похож на объем блока, который имеет C. JavaScript по умолчанию не имеет области действия уровня блока, поэтому внутри forцикла это типичная проблема. Лексическая область действия для JavaScript есть только на уровне функций, если не используется ES6 letили const.
icc97

275

Давайте попробуем самое короткое определение:

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

Это все, что нужно сделать!


21
Последняя часть: «даже если родительская функция вернулась» называется Closure.
Хуанма Менендес

1
Лексический обзор и закрытие поняли только за один день. Спасибо!!
Подземелье

63
var scope = "I am global";
function whatismyscope(){
   var scope = "I am just a local";
   function func() {return scope;}
   return func;
}

whatismyscope()()

Приведенный выше код будет возвращать «Я просто местный». Не вернется «Я глобальный». Потому что функция func () считает, где изначально было определено, что находится в области действия whatismyscope.

Он не будет беспокоиться о том, как он вызывается (глобальная область действия / даже из другой функции), поэтому значение глобальной области действия, которое я являюсь глобальным, не будет напечатано.

Это называется лексической областью видимости, где « функции выполняются с использованием цепочки областей действия, которая действовала, когда они были определены » - в соответствии с Руководством по определению JavaScript.

Лексическая сфера - очень очень мощная концепция.

Надеюсь это поможет..:)


3
Это очень хорошее объяснение, я хочу добавить еще одну вещь, если вы напишите функцию func () {return this.scope;}, тогда она вернет «Я глобален», просто используйте это ключевое слово, и ваша сфера изменится
Раджеш Кумар Бхавсар

41

Лексическая (AKA static) область действия относится к определению области действия переменной на основе исключительно ее положения в текстовом корпусе кода. Переменная всегда относится к ее среде верхнего уровня. Это хорошо понимать по отношению к динамическому объему.


41

Область действия определяет область, в которой доступны функции, переменные и тому подобное. Доступность переменной, например, определяется в ее контексте, скажем, в функции, файле или объекте, в котором они определены. Мы обычно называем эти локальные переменные.

Лексическая часть означает, что вы можете извлечь область из чтения исходного кода.

Лексическая область действия также известна как статическая область действия.

Динамическая область действия определяет глобальные переменные, которые можно вызывать или ссылаться из любого места после их определения. Иногда их называют глобальными переменными, хотя глобальные переменные в большинстве языков программирования имеют лексическую область. Это означает, что из чтения кода можно получить информацию о том, что переменная доступна в этом контексте. Может быть, нужно следовать условию использования или включения, чтобы найти указание или определение, но код / ​​компилятор знает о переменной в этом месте.

Напротив, в динамической области поиска сначала выполняется поиск в локальной функции, затем поиск в функции, которая вызвала локальную функцию, затем поиск в функции, которая вызвала эту функцию, и т. Д. По стеку вызовов. «Динамический» относится к изменению в том смысле, что стек вызовов может отличаться каждый раз, когда вызывается данная функция, и поэтому функция может попадать в разные переменные в зависимости от того, откуда она вызывается. (см. здесь )

Чтобы увидеть интересный пример для динамического объема см. Здесь .

Для более подробной информации смотрите здесь и здесь .

Некоторые примеры в Delphi / Object Pascal

Delphi имеет лексическую область применения.

unit Main;
uses aUnit;  // makes available all variables in interface section of aUnit

interface

  var aGlobal: string; // global in the scope of all units that use Main;
  type 
    TmyClass = class
      strict private aPrivateVar: Integer; // only known by objects of this class type
                                    // lexical: within class definition, 
                                    // reserved word private   
      public aPublicVar: double;    // known to everyboday that has access to a 
                                    // object of this class type
    end;

implementation

  var aLocalGlobal: string; // known to all functions following 
                            // the definition in this unit    

end.

Ближайший Delphi к динамической области видимости - это пара функций RegisterClass () / GetClass (). Для его использования см. Здесь .

Скажем, время, когда RegisterClass ([TmyClass]) вызывается для регистрации определенного класса, нельзя предсказать, прочитав код (он вызывается в методе нажатия кнопки, вызываемом пользователем), код, вызывающий GetClass ('TmyClass'), получит результат или нет. Вызов RegisterClass () не обязательно должен быть в лексической области модуля, использующего GetClass ();

Другая возможность для динамической области видимости - это анонимные методы (замыкания) в Delphi 2009, поскольку они знают переменные своей вызывающей функции. Он не следует пути вызова оттуда рекурсивно и поэтому не является полностью динамическим.


2
На самом деле private доступен во всем модуле, где определен класс. Вот почему «Строгий приват» был представлен в D2006.
Марко ван де Воорт

2
+1 для простого языка (в отличие от сложного языка и примеров без особого описания)
Pops

36

Мне нравятся полнофункциональные, независимые от языка ответы от таких людей, как @Arak. Так как этот вопрос был помечен как JavaScript , я хотел бы добавить некоторые заметки, специфичные для этого языка.

В JavaScript наш выбор области видимости:

  • как есть (без регулировки объема)
  • лексический var _this = this; function callback(){ console.log(_this); }
  • связанный callback.bind(this)

Стоит отметить, я думаю, что JavaScript не имеет динамической области видимости . .bindкорректирует thisключевое слово, и это близко, но технически не то же самое.

Вот пример, демонстрирующий оба подхода. Вы делаете это каждый раз, когда принимаете решение о том, как настроить обратные вызовы, чтобы это относилось к обещаниям, обработчикам событий и многому другому.

лексический

Вот что вы можете Lexical Scopingназвать обратными вызовами в JavaScript:

var downloadManager = {
  initialize: function() {
    var _this = this; // Set up `_this` for lexical access
    $('.downloadLink').on('click', function () {
      _this.startDownload();
    });
  },
  startDownload: function(){
    this.thinking = true;
    // Request the file from the server and bind more callbacks for when it returns success or failure
  }
  //...
};

Связанный

Еще один способ охвата заключается в использовании Function.prototype.bind:

var downloadManager = {
  initialize: function() {
    $('.downloadLink').on('click', function () {
      this.startDownload();
    }.bind(this)); // Create a function object bound to `this`
  }
//...

Эти методы, насколько мне известно, поведенчески эквивалентны.


Использование bindне влияет на объем.
Бен Астон

12

Лексическая область видимости: переменные, объявленные вне функции, являются глобальными переменными и видны везде в программе JavaScript. Переменные, объявленные внутри функции, имеют область видимости функции и видны только коду, который появляется внутри этой функции.


12

IBM определяет это как:

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

Пример 1:

function x() {
    /*
    Variable 'a' is only available to function 'x' and function 'y'.
    In other words the area defined by 'x' is the lexical scope of
    variable 'a'
    */
    var a = "I am a";

    function y() {
        console.log( a )
    }
    y();

}
// outputs 'I am a'
x();

Пример 2:

function x() {

    var a = "I am a";

    function y() {
         /*
         If a nested routine declares an item with the same name,
         the outer item is not available in the nested routine.
         */
        var a = 'I am inner a';
        console.log( a )
    }
    y();

}
// outputs 'I am inner a'
x();

8

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

function grandfather() {
    var name = 'Hammad';
    // 'likes' is not accessible here
    function parent() {
        // 'name' is accessible here
        // 'likes' is not accessible here
        function child() {
            // Innermost level of the scope chain
            // 'name' is also accessible here
            var likes = 'Coding';
        }
    }
}

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

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

Обратите внимание, что это взято отсюда .


8

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

Пример:

let str="JavaScript";

const myFun = () => {
    console.log(str);
}

myFun();

// Вывод: JavaScript


2
Самый короткий и лучший ответ для меня на примере. Можно было бы добавить, что функции стрелки ES6 'решают проблему с bind. С ними bindбольше не требуется. Для получения дополнительной информации об этом изменении проверьте stackoverflow.com/a/34361380/11127383
Даниэль Danielecki

4

В нем отсутствует важная часть разговора о лексической и динамической области видимости : простое объяснение времени жизни переменной области действия - или когда к переменной можно получить доступ.

Динамическое определение объема лишь очень слабо соответствует «глобальному» определению в том смысле, в котором мы традиционно думаем об этом (причина, по которой я привожу сравнение между ними, заключается в том, что оно уже упоминалось - и мне не особенно нравится связанный объяснение статье ); вероятно, лучше всего не проводить сравнение между глобальным и динамическим - хотя, согласно предположительной статье, «... [это] полезно в качестве замены глобально изменяемых переменных».

Итак, на простом английском языке, в чем заключается важное различие между двумя механизмами определения объема?

Лексическая область видимости была очень хорошо определена в ответах выше: переменные с лексической областью доступны - или доступны - на локальном уровне функции, в которой они были определены.

Однако, поскольку это не является предметом OP, динамическое определение области не получило большого внимания, и внимание, которое он получил, означает, что, вероятно, нужно немного больше (это не критика других ответов, а скорее "о, этот ответ заставил нас пожелать, чтобы было немного больше)). Итак, вот еще немного:

Динамическое определение объема означает, что переменная доступна для более крупной программы в течение времени жизни вызова функции - или во время выполнения функции. На самом деле, Википедия действительно хорошо справляется с объяснением различий между ними. Чтобы не запутывать это, вот текст, который описывает динамическую область видимости:

... [I] n динамическая область видимости (или динамическая область действия), если область действия имени переменной является определенной функцией, то ее область действия - это период времени, в течение которого функция выполняется: во время выполнения функции имя переменной существует , и привязан к своей переменной, но после возврата из функции имя переменной не существует.


3

Лексическая область действия означает, что функция ищет переменные в контексте, в котором она была определена, а не в области непосредственно вокруг нее.

Посмотрите, как работает лексическая область видимости в Лиспе, если вы хотите больше подробностей. Выбранный ответ Кайл Кронин в динамических и лексических переменных в Common Lisp намного яснее, чем ответы здесь.

По совпадению я узнал об этом только в классе Lisp, и это применимо и в JavaScript.

Я запустил этот код в консоли Chrome.

// JavaScript               Equivalent Lisp
var x = 5;                //(setf x 5)
console.debug(x);         //(print x)
function print_x(){       //(defun print-x ()
    console.debug(x);     //    (print x)
}                         //)
(function(){              //(let
    var x = 10;           //    ((x 10))
    console.debug(x);     //    (print x)
    print_x();            //    (print-x)
})();                     //)

Вывод:

5
10
5

3

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

Эта концепция широко используется в замыканиях в JavaScript.

Допустим, у нас есть код ниже.

var x = 2;
var add = function() {
    var y = 1;
    return x + y;
};

Теперь, когда вы вызываете add () -> это напечатает 3.

Итак, функция add () обращается к глобальной переменной, xкоторая определена перед функцией метода add. Это вызвано лексическим ограничением в JavaScript.


Учтите, что фрагмент кода предназначен для языка с динамической областью действия. Если add()функция вызывается сразу после данного фрагмента кода, она также выдает 3. Лексическое определение не просто означает, что функция может обращаться к глобальным переменным вне локального контекста. Так что пример кода действительно не помогает показать, что означает лексическая область видимости. Чтобы показать лексическую область видимости в коде, нужен контрпример или хотя бы объяснение других возможных интерпретаций кода.
С Перкинс

2

Лексическая область действия относится к лексикону идентификаторов (например, переменных, функций и т. Д.), Видимых из текущей позиции в стеке выполнения.

- global execution context
    - foo
    - bar
    - function1 execution context
        - foo2
        - bar2
        - function2 execution context
            - foo3
            - bar3

foo а также bar всегда находятся в пределах лексикона доступных идентификаторов, потому что они являются глобальными.

Когда function1выполняется, он имеет доступ к лексике foo2, bar2, foo, и bar.

когда function2 выполняется, он имеет доступ к лексике foo3, bar3, foo2, bar2, foo, иbar .

Причина, по которой глобальные и / или внешние функции не имеют доступа к внутренним идентификаторам функций, заключается в том, что выполнение этой функции еще не произошло, и поэтому ни один из ее идентификаторов не был выделен для памяти. Более того, после выполнения этого внутреннего контекста он удаляется из стека выполнения, а это означает, что все его идентификаторы были собраны сборщиком мусора и более недоступны.

Наконец, именно поэтому вложенный контекст выполнения ВСЕГДА может получить доступ к контексту выполнения своих предков и, следовательно, почему он имеет доступ к большему лексикону идентификаторов.

Видеть:

Отдельное спасибо @ robr3rd за помощь в упрощении приведенного выше определения.


1

Вот другой угол в этом вопросе, который мы можем получить, сделав шаг назад и посмотрев на роль определения масштаба в более широком контексте интерпретации (запуска программы). Другими словами, представьте, что вы создавали интерпретатор (или компилятор) для языка и отвечали за вычисление вывода, учитывая программу и некоторый вклад в нее.

Интерпретация предполагает отслеживание трех вещей:

  1. Состояние, а именно: переменные и ссылки на ячейки памяти в куче и стеке.

  2. Операции в этом состоянии, а именно, каждая строка кода в вашей программе

  3. Среда , в которой данная операция выполняется , а именно - проекция состояния на операцию.

Интерпретатор начинает с первой строки кода в программе, вычисляет ее среду, запускает строку в этой среде и фиксирует ее влияние на состояние программы. Затем он следует потоку управления программы для выполнения следующей строки кода и повторяет процесс до завершения программы.

Вы вычисляете среду для любой операции с помощью формального набора правил, определенных языком программирования. Термин «привязка» часто используется для описания отображения общего состояния программы на значение в среде. Обратите внимание, что под «общим состоянием» мы подразумеваем не глобальное состояние, а скорее общую сумму каждого достижимого определения в любой точке выполнения).

Это основа, в которой определяется область видимости. Теперь перейдем к следующей части наших возможностей.

  • Как разработчик интерпретатора, вы могли бы упростить вашу задачу, сделав среду максимально приближенной к состоянию программы. Соответственно, среда строки кода будет просто определяться средой предыдущей строки кода с эффектами этой операции, примененной к ней, независимо от того, была ли предыдущая строка присваиванием, вызовом функции, возвращаемым из функции, или управляющая структура, такая как цикл while.

Это суть динамической области видимости , при которой среда, в которой выполняется любой код, связана с состоянием программы, определяемым ее контекстом выполнения.

  • Или вы можете подумать о программисте, использующем ваш язык, и упростить его или ее задачу отслеживания значений, которые может принимать переменная. Существует слишком много путей и слишком много сложностей, связанных с рассуждением об итогах всего выполнения. Lexical Scoping помогает сделать это, ограничивая текущую среду частью состояния, определенной в текущем блоке, функции или другой единице области видимости, и его родительском элементе (т. Е. Блоке, включающем текущие часы, или функции, вызвавшей текущую функцию).

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


0

Древний вопрос, но вот мой взгляд на него.

Лексическая (статическая) область действия относится к области действия переменной в исходном коде. .

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

Чтобы проиллюстрировать это:

var a='apple';

function doit() {
    var a='aardvark';
    return function() {
        alert(a);
    }
}

var test=doit();
test();

В этом примере переменная aопределена глобально, но затенена в doit()функции. Эта функция возвращает другую функцию, которая, как вы видите, опирается наa переменную вне своей области видимости.

Если вы запустите это, вы обнаружите, что используемое значение есть aardvark, а не appleкакое, хотя оно находится в области действияtest() функции, не входит в лексическую область исходной функции. То есть используемая область - это область, как она появляется в исходном коде, а не область, где функция фактически используется.

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

var a='apple',b='banana';

function init() {
  var a='aardvark',b='bandicoot';
  document.querySelector('button#a').onclick=function(event) {
    alert(a);
  }
  document.querySelector('button#b').onclick=doB;
}

function doB(event) {
  alert(b);
}

init();
<button id="a">A</button>
<button id="b">B</button>

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

Кстати, в обоих примерах вы также заметите, что внутренние лексически изменяемые переменные сохраняются, даже несмотря на то, что содержащая функция функция работает. Это называется закрытием и относится к доступу вложенной функции к внешним переменным, даже если внешняя функция завершена. JavaScript должен быть достаточно умным, чтобы определить, не нужны ли эти переменные, и если нет, может ли их собрать мусор.


-1

Я обычно учусь на примере, и вот кое-что:

const lives = 0;

function catCircus () {
    this.lives = 1;
    const lives = 2;

    const cat1 = {
        lives: 5,
        jumps: () => {
            console.log(this.lives);
        }
    };
    cat1.jumps(); // 1
    console.log(cat1); // { lives: 5, jumps: [Function: jumps] }

    const cat2 = {
        lives: 5,
        jumps: () => {
            console.log(lives);
        }
    };
    cat2.jumps(); // 2
    console.log(cat2); // { lives: 5, jumps: [Function: jumps] }

    const cat3 = {
        lives: 5,
        jumps: () => {
            const lives = 3;
            console.log(lives);
        }
    };
    cat3.jumps(); // 3
    console.log(cat3); // { lives: 5, jumps: [Function: jumps] }

    const cat4 = {
        lives: 5,
        jumps: function () {
            console.log(lives);
        }
    };
    cat4.jumps(); // 2
    console.log(cat4); // { lives: 5, jumps: [Function: jumps] }

    const cat5 = {
        lives: 5,
        jumps: function () {
            var lives = 4;
            console.log(lives);
        }
    };
    cat5.jumps(); // 4
    console.log(cat5); // { lives: 5, jumps: [Function: jumps] }

    const cat6 = {
        lives: 5,
        jumps: function () {
            console.log(this.lives);
        }
    };
    cat6.jumps(); // 5
    console.log(cat6); // { lives: 5, jumps: [Function: jumps] }

    const cat7 = {
        lives: 5,
        jumps: function thrownOutOfWindow () {
            console.log(this.lives);
        }
    };
    cat7.jumps(); // 5
    console.log(cat7); // { lives: 5, jumps: [Function: thrownOutOfWindow] }
}

catCircus();

-1

Эта тема тесно связана со встроенной bindфункцией и представлена ​​в ECMAScript 6 Arrow Functions . Это действительно раздражало, потому что для каждого нового метода «класса» (на самом деле, функции), который мы хотели использовать, нам приходилось bindэто делать, чтобы иметь доступ к области действия.

JavaScript по умолчанию не устанавливает его объем thisна функции (она не устанавливает контекст на this). По умолчанию вы должны явно указать, какой контекст вы хотите иметь.

Функции стрелки автоматически получают так называемую лексическую область видимости (имеют доступ к определению переменной в содержащем ее блоке). При использовании функций со стрелками он автоматически связывается thisс местом, где функция со стрелкой была определена в первую очередь, и контекст этой функции со стрелкой является содержащим его блоком.

Посмотрите, как это работает на практике, на простейших примерах ниже.

Перед стрелками (без лексической области по умолчанию):

const programming = {
  language: "JavaScript",
  getLanguage: function() {
    return this.language;
  }
}

const globalScope = programming.getLanguage;
console.log(globalScope()); // Output: undefined

const localScope = programming.getLanguage.bind(programming);
console.log(localScope()); // Output: "JavaScript"

С функциями стрелок (лексическая область по умолчанию):

const programming = {
  language: "JavaScript",
  getLanguage: function() {
    return this.language;
  }
}

const arrowFunction = () => {
    console.log(programming.getLanguage());
}

arrowFunction(); // Output: "JavaScript"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.