Co to jest krótkie wprowadzenie do zakresu leksykalnego?
Co to jest krótkie wprowadzenie do zakresu leksykalnego?
Odpowiedzi:
Rozumiem je poprzez przykłady. :)
Po pierwsze, zakres leksykalny (zwany również zakresem statycznym ), w składni podobnej do C:
void fun()
{
int x = 5;
void fun2()
{
printf("%d", x);
}
}
Każdy poziom wewnętrzny może uzyskać dostęp do swoich zewnętrznych poziomów.
Istnieje inny sposób, zwany zakresem dynamicznym, używany przez pierwszą implementację Lisp , ponownie w składni podobnej do C:
void fun()
{
printf("%d", x);
}
void dummy1()
{
int x = 5;
fun();
}
void dummy2()
{
int x = 10;
fun();
}
Tu fun
można albo dostęp x
w dummy1
lub dummy2
lub dowolny x
w dowolnej funkcji rozmowy fun
z x
zadeklarowanym w nim.
dummy1();
wydrukuje 5,
dummy2();
wydrukuje 10.
Pierwszy nazywa się statyczny, ponieważ można go wywnioskować w czasie kompilacji, a drugi nazywa się dynamiczny, ponieważ zakres zewnętrzny jest dynamiczny i zależy od wywołania łańcucha funkcji.
Uważam, że statyczne ustalanie zakresu jest łatwiejsze dla oka. W końcu większość języków poszła w ten sposób, nawet Lisp (może zrobić oba, prawda?). Dynamiczne określanie zakresu jest jak przekazywanie referencji wszystkich zmiennych do wywoływanej funkcji.
Jako przykład tego, dlaczego kompilator nie może wydedukować zewnętrznego zakresu dynamicznego funkcji, rozważmy nasz ostatni przykład. Jeśli napiszemy coś takiego:
if(/* some condition */)
dummy1();
else
dummy2();
Łańcuch połączeń zależy od warunku czasu wykonywania. Jeśli to prawda, łańcuch połączeń wygląda następująco:
dummy1 --> fun()
Jeśli warunek jest fałszywy:
dummy2 --> fun()
Zewnętrzny zakres fun
w obu przypadkach to osoba dzwoniąca plus osoba dzwoniąca i tak dalej .
Wystarczy wspomnieć, że język C nie pozwala na zagnieżdżanie funkcji ani dynamiczne określanie zakresu.
JavaScript
. Dlatego uważam, że nie należy tego oznaczać jako przyjętej odpowiedzi. Zakres leksykalny szczególnie w JS jest inny
for
typowym problemem jest pętla. Zakres leksykalny JavaScript jest tylko na poziomie funkcji, chyba że używany jest ES6 let
lub const
.
Spróbujmy najkrótszej możliwej definicji:
Schemat leksykalny określa, w jaki sposób nazwy zmiennych są rozwiązywane w funkcjach zagnieżdżonych: funkcje wewnętrzne zawierają zakres funkcji nadrzędnych, nawet jeśli funkcja nadrzędna powróciła .
To wszystko!
var scope = "I am global";
function whatismyscope(){
var scope = "I am just a local";
function func() {return scope;}
return func;
}
whatismyscope()()
Powyższy kod zwróci „Jestem tylko lokalnym”. Nie zwróci „Jestem globalny”. Ponieważ funkcja func () liczy, gdzie została pierwotnie zdefiniowana, co jest objęte zakresem funkcji whatismyscope.
Nie będzie to przeszkadzało, niezależnie od tego, jak się nazywa (zakres globalny / nawet z innej funkcji), dlatego wartość zakresu globalnego, którym jestem globalny, nie zostanie wydrukowana.
Nazywa się to zasięgiem leksykalnym, w którym „ funkcje są wykonywane przy użyciu łańcucha zasięgu, który obowiązywał podczas ich definiowania ” - zgodnie z Przewodnikiem po definicji JavaScript.
Zakres leksykalny jest bardzo potężną koncepcją.
Mam nadzieję że to pomoże..:)
Określanie zakresu leksykalnego (AKA static) odnosi się do określania zakresu zmiennej wyłącznie na podstawie jej pozycji w tekstowym korpusie kodu. Zmienna zawsze odnosi się do środowiska najwyższego poziomu. Dobrze jest to zrozumieć w odniesieniu do zakresu dynamicznego.
Zakres określa obszar, w którym dostępne są funkcje, zmienne i tym podobne. Na przykład dostępność zmiennej jest zdefiniowana w jej kontekście, powiedzmy funkcja, plik lub obiekt, w którym są zdefiniowane. Zwykle nazywamy te zmienne lokalne.
Część leksykalna oznacza, że zakres można odczytać z odczytu kodu źródłowego.
Zakres leksykalny jest również znany jako zakres statyczny.
Zakres dynamiczny definiuje zmienne globalne, które można wywoływać lub do których można się odwoływać z dowolnego miejsca po zdefiniowaniu. Czasami nazywane są zmiennymi globalnymi, nawet jeśli zmienne globalne w większości języków programowania mają zakres leksykalny. Oznacza to, że można odczytać kod, że zmienna jest dostępna w tym kontekście. Być może trzeba zastosować klauzulę use lub include, aby znaleźć instancję lub definicję, ale kod / kompilator wie o zmiennej w tym miejscu.
Natomiast w dynamicznym określaniu zakresu najpierw wyszukujesz w funkcji lokalnej, a następnie w funkcji, która wywołała funkcję lokalną, a następnie w funkcji, która wywołała tę funkcję i tak dalej, w górę stosu wywołań. „Dynamiczny” odnosi się do zmiany, polegającej na tym, że stos wywołań może być różny za każdym razem, gdy wywoływana jest dana funkcja, a zatem funkcja może uderzać w różne zmienne w zależności od tego, skąd została wywołana. (patrz tutaj )
Aby zobaczyć ciekawy przykład zakresu dynamicznego, zobacz tutaj .
Więcej informacji można znaleźć tutaj i tutaj .
Kilka przykładów w Delphi / Object Pascal
Delphi ma zakres leksykalny.
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.
Najbardziej zbliżone do zakresu dynamicznego Delphi to para funkcji RegisterClass () / GetClass (). Aby zobaczyć jego użycie, zobacz tutaj .
Powiedzmy, że czas wywołania RegisterClass ([TmyClass]) w celu zarejestrowania określonej klasy nie może być przewidziany przez odczytanie kodu (jest wywoływany w metodzie kliknięcia przycisku wywoływanej przez użytkownika), kod wywołujący GetClass („TmyClass”) otrzyma wynik czy nie. Wywołanie funkcji RegisterClass () nie musi znajdować się w zakresie leksykalnym jednostki za pomocą GetClass ();
Inną możliwością dla zakresu dynamicznego są metody anonimowe (zamknięcia) w Delphi 2009, ponieważ znają zmienne swojej funkcji wywołującej. Nie podąża stamtąd rekurencyjnie ścieżką wywoływania, a zatem nie jest w pełni dynamiczna.
Uwielbiam w pełni funkcjonalne, niezależne od języka odpowiedzi od ludzi takich jak @Arak. Ponieważ to pytanie zostało oznaczone JavaScript , chciałbym zagłębić się w notatki bardzo specyficzne dla tego języka.
W JavaScript wybieramy zakres:
var _this = this; function callback(){ console.log(_this); }
callback.bind(this)
Myślę, że warto zauważyć, że JavaScript nie ma tak naprawdę dynamicznego zakresu . .bind
dostosowuje this
słowo kluczowe i jest blisko, ale technicznie nie jest takie samo.
Oto przykład demonstrujący oba podejścia. Robisz to za każdym razem, gdy podejmujesz decyzję o sposobie określania zakresu wywołań zwrotnych, więc dotyczy to obietnic, procedur obsługi zdarzeń i innych.
Oto, co możesz Lexical Scoping
nazwać zwrotnymi w 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
}
//...
};
Innym sposobem na zasięg jest użycie Function.prototype.bind
:
var downloadManager = {
initialize: function() {
$('.downloadLink').on('click', function () {
this.startDownload();
}.bind(this)); // Create a function object bound to `this`
}
//...
O ile mi wiadomo, metody te są równoważne behawioralnie.
bind
nie wpływa na zakres.
IBM definiuje to jako:
Część programu lub jednostki segmentu, w której obowiązuje deklaracja. Identyfikator zadeklarowany w procedurze jest znany w tej procedurze i we wszystkich procedurach zagnieżdżonych. Jeśli procedura zagnieżdżona deklaruje element o tej samej nazwie, element zewnętrzny nie jest dostępny w procedurze zagnieżdżonej.
Przykład 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();
Przykład 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();
Zakres leksykalny oznacza, że w zagnieżdżonej grupie funkcji funkcje wewnętrzne mają dostęp do zmiennych i innych zasobów ich zakresu nadrzędnego . Oznacza to, że funkcje potomne są leksykalnie powiązane z kontekstem wykonania ich rodziców. Zakres leksykalny jest czasem określany również jako zakres statyczny .
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';
}
}
}
Rzeczą, którą zauważysz w zakresie leksykalnym, jest to, że działa on naprzód, co oznacza, że nazwa jest dostępna w kontekstach wykonawczych jego dzieci. Ale nie działa wstecz na swoich rodziców, co oznacza, że rodzice likes
nie mogą uzyskać dostępu do zmiennej .
Mówi nam to również, że zmienne o tej samej nazwie w różnych kontekstach wykonywania zyskują pierwszeństwo od góry do dołu stosu wykonania. Zmienna o nazwie podobnej do innej zmiennej w najbardziej wewnętrznej funkcji (najwyższy kontekst stosu wykonawczego) będzie miała wyższy priorytet.
Pamiętaj, że jest to pobierane stąd .
W prostym języku zakres leksykalny jest zmienną zdefiniowaną poza twoim zakresem lub górny zakres jest automatycznie dostępny w twoim zasięgu, co oznacza, że nie musisz go tam przekazywać.
Przykład:
let str="JavaScript";
const myFun = () => {
console.log(str);
}
myFun();
// Dane wyjściowe: JavaScript
bind
. Dzięki nim bind
nie jest już wymagany. Aby uzyskać więcej informacji o tej zmianie, sprawdź stackoverflow.com/a/34361380/11127383
Brakuje ważnej części rozmowy dotyczącej zakresu leksykalnego i dynamicznego : proste wyjaśnienie okresu istnienia zmiennej o zasięgu lub kiedy można uzyskać do niej dostęp.
Dynamiczne określanie zakresu bardzo luźno odpowiada zakresowi określanemu „globalnie” w sposób, w jaki tradycyjnie o nim myślimy (powodem, dla którego przywołuję porównanie między nimi, jest to, że zostało już wspomniane - i nie podoba mi się szczególnie wyjaśnienie powiązanego artykułu ); prawdopodobnie najlepiej nie porównujemy globalnego i dynamicznego - choć podobno, zgodnie z powiązanym artykułem, „... [to] jest przydatne jako substytut zmiennych o zasięgu globalnym”.
Więc, w prostym języku angielskim, jakie jest ważne rozróżnienie między tymi dwoma mechanizmami określania zakresu?
Zakres leksykalny został bardzo dobrze zdefiniowany we wszystkich powyższych odpowiedziach: zmienne o zasięgu leksykalnym są dostępne - lub dostępne - na poziomie lokalnym funkcji, w której zostały zdefiniowane.
Jednak - ponieważ nie jest to cel PO - dynamiczne ustalanie zakresu nie spotkało się z dużym zainteresowaniem, a uwaga, którą otrzymała oznacza, że prawdopodobnie potrzebuje trochę więcej (nie jest to krytyka innych odpowiedzi, ale raczej „och, ta odpowiedź sprawiła, że żałujemy, że nie było trochę więcej ”). Oto trochę więcej:
Dynamiczne określanie zakresu oznacza, że zmienna jest dostępna dla większego programu przez cały czas trwania wywołania funkcji - lub podczas wykonywania funkcji. Naprawdę Wikipedia naprawdę dobrze sobie radzi z wyjaśnieniem różnicy między nimi. Aby go nie zaciemniać, oto tekst opisujący dynamiczne określanie zakresu:
... [I] W zakresie dynamicznym (lub zakresie dynamicznym), jeśli zakres nazwy zmiennej jest pewną funkcją, wówczas jej zasięg jest okresem czasu, w którym funkcja się wykonuje: podczas działania funkcji nazwa zmiennej istnieje i jest powiązany ze swoją zmienną, ale po powrocie funkcji nazwa zmiennej nie istnieje.
Zasięg leksykalny oznacza, że funkcja wyszukuje zmienne w kontekście, w którym została zdefiniowana, a nie w zasięgu wokół niej.
Zobacz, jak działa zakres leksykalny w Lisp, jeśli chcesz uzyskać więcej szczegółów. Wybrana odpowiedź Kyle'a Cronina w zmiennych dynamicznych i leksykalnych w Common Lisp jest o wiele jaśniejsza niż odpowiedzi tutaj.
Przypadkowo dowiedziałem się o tym tylko w klasie Lisp, a zdarza się to również w JavaScript.
Uruchomiłem ten kod w konsoli 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)
})(); //)
Wynik:
5
10
5
Zakres leksykalny w JavaScript oznacza, że zmienna zdefiniowana poza funkcją może być dostępna wewnątrz innej funkcji zdefiniowanej po deklaracji zmiennej. Ale przeciwieństwo nie jest prawdą; zmienne zdefiniowane w funkcji nie będą dostępne poza tą funkcją.
Ta koncepcja jest szeroko stosowana w zamknięciach w JavaScript.
Powiedzmy, że mamy poniższy kod.
var x = 2;
var add = function() {
var y = 1;
return x + y;
};
Teraz, kiedy wywołasz add () -> to wydrukuje 3.
Tak więc funkcja add () uzyskuje dostęp do zmiennej globalnej, x
która jest zdefiniowana przed dodaniem funkcji metody. Jest to wywoływane ze względu na zakres leksykalny w JavaScript.
add()
funkcja zostanie wywołana bezpośrednio po danym fragmencie kodu, wypisze również 3. Zasięg leksykalny nie oznacza po prostu, że funkcja może uzyskać dostęp do zmiennych globalnych poza kontekstem lokalnym. Tak więc przykładowy kod naprawdę nie pomaga pokazać, co oznacza zakres leksykalny. Pokazanie leksykalnego zakresu w kodzie naprawdę wymaga licznika lub przynajmniej wyjaśnienia innych możliwych interpretacji kodu.
Zakres leksykalny odnosi się do leksykonu identyfikatorów (np. Zmiennych, funkcji itp.) Widocznych z bieżącej pozycji na stosie wykonania.
- global execution context
- foo
- bar
- function1 execution context
- foo2
- bar2
- function2 execution context
- foo3
- bar3
foo
i bar
zawsze znajdują się w leksykonie dostępnych identyfikatorów, ponieważ są globalne.
Kiedy function1
jest wykonywana, że ma dostęp do leksykonu foo2
, bar2
, foo
, i bar
.
Kiedy function2
jest wykonywana, że ma dostęp do leksykonu foo3
, bar3
, foo2
, bar2
, foo
, i bar
.
Powodem, dla którego funkcje globalne i / lub zewnętrzne nie mają dostępu do identyfikatorów funkcji wewnętrznych, jest to, że wykonanie tej funkcji jeszcze nie nastąpiło i dlatego żaden z jej identyfikatorów nie został przydzielony do pamięci. Co więcej, po uruchomieniu wewnętrznego kontekstu jest on usuwany ze stosu wykonawczego, co oznacza, że wszystkie jego identyfikatory zostały wyrzucone do pamięci i nie są już dostępne.
Wreszcie, dlatego zagnieżdżony kontekst wykonania może ZAWSZE uzyskać dostęp do kontekstu wykonania przodków, a tym samym ma dostęp do większej leksykonu identyfikatorów.
Widzieć:
Specjalne podziękowania dla @ robr3rd za pomoc w uproszczeniu powyższej definicji.
Oto inny punkt widzenia na to pytanie, który możemy uzyskać, cofając się o krok i patrząc na rolę określania zakresu w szerszych ramach interpretacji (uruchamianie programu). Innymi słowy, wyobraź sobie, że budujesz interpreter (lub kompilator) dla języka i jesteś odpowiedzialny za obliczenie wyniku, biorąc pod uwagę program i pewne dane wejściowe.
Interpretacja obejmuje śledzenie trzech rzeczy:
Stan - mianowicie zmienne i odnośne lokalizacje pamięci na stercie i stosie.
Operacje w tym stanie - mianowicie każdy wiersz kodu w twoim programie
Środowisko , w którym dana operacja przebiega - mianowicie rzut stanu w operacji.
Tłumacz rozpoczyna się od pierwszego wiersza kodu w programie, oblicza jego środowisko, uruchamia wiersz w tym środowisku i rejestruje jego wpływ na stan programu. Następnie wykonuje kontrolę programu, aby wykonać następny wiersz kodu, i powtarza proces aż do zakończenia programu.
Sposób obliczania środowiska dla dowolnej operacji odbywa się za pomocą formalnego zestawu reguł określonych przez język programowania. Termin „wiązanie” jest często używany do opisania odwzorowania ogólnego stanu programu na wartość w środowisku. Zauważ, że przez „stan ogólny” nie rozumiemy stanu globalnego, ale sumę wszystkich możliwych do osiągnięcia definicji w dowolnym momencie wykonania).
Jest to struktura, w której zdefiniowano problem określania zakresu. Teraz do następnej części naszych opcji.
Jest to sedno dynamicznego określania zakresu , w którym środowisko, w którym działa dowolny kod, jest powiązane ze stanem programu określonym przez kontekst jego wykonania.
Innymi słowy, w zakresie leksykalnym środowisko, które widzi każdy kod, jest powiązane ze stanem powiązanym z zakresem zdefiniowanym jawnie w języku, takim jak blok lub funkcja.
Starożytne pytanie, ale oto moje zdanie.
Zakres leksykalny (statyczny) odnosi się do zakresu zmiennej w kodzie źródłowym .
W języku takim jak JavaScript, w którym funkcje mogą być przekazywane i dołączane oraz ponownie dołączane do różnych obiektów, możesz mieć taki zakres, który zależy od tego, kto wywołuje funkcję w danym momencie, ale tak nie jest. Zmiana zakresu w ten sposób byłaby zakresem dynamicznym, a JavaScript tego nie robi, chyba że z this
odniesieniem do obiektu.
Aby zilustrować tę kwestię:
var a='apple';
function doit() {
var a='aardvark';
return function() {
alert(a);
}
}
var test=doit();
test();
W tym przykładzie zmienna a
jest zdefiniowana globalnie, ale jest zaciemniona w doit()
funkcji. Ta funkcja zwraca inną funkcję, która, jak widać, opiera się na a
zmiennej poza własnym zasięgiem.
Jeśli to uruchomisz, przekonasz się, że użyta wartość aardvark
nie jest tym , apple
co, choć jest objęte zakresem test()
funkcji, nie znajduje się w zakresie leksykalnym oryginalnej funkcji. Oznacza to, że zastosowany zakres jest zakresem, jaki pojawia się w kodzie źródłowym, a nie zakresem, w którym funkcja jest faktycznie używana.
Ten fakt może mieć irytujące konsekwencje. Na przykład możesz zdecydować, że łatwiej jest zorganizować swoje funkcje osobno, a następnie użyć ich, gdy nadejdzie odpowiedni czas, na przykład w module obsługi zdarzeń:
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>
Ten przykładowy kod wykonuje jedną z nich. Widać, że z powodu zakresu leksykalnego przycisk A
używa zmiennej wewnętrznej, a przycisk B
nie. Możesz zagnieżdżać funkcje bardziej, niż byś chciał.
Nawiasem mówiąc, w obu przykładach zauważysz również, że wewnętrzne zmienne o leksykalnym zasięgu pozostają, nawet jeśli funkcja zawierająca funkcję przeszła swój bieg. Nazywa się to zamknięciem i odnosi się do dostępu zagnieżdżonej funkcji do zmiennych zewnętrznych, nawet jeśli funkcja zewnętrzna zakończyła się. JavaScript musi być wystarczająco inteligentny, aby określić, czy te zmienne nie są już potrzebne, a jeśli nie, może je wyrzucić.
Zwykle uczę się na przykładach, a oto coś:
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();
Temat ten jest ściśle powiązany z wbudowaną bind
funkcją i wprowadzony w ECMAScript 6 Funkcje strzałek . To było naprawdę denerwujące, ponieważ dla każdej nowej metody „klasy” (właściwie funkcji), której chcieliśmy użyć, musieliśmybind
, aby mieć dostęp do zakresu.
JavaScript domyślnie nie określa zakres jego this
funkcji (to nie ustawia kontekst on this
). Domyślnie musisz wyraźnie powiedzieć, który kontekst chcesz mieć.
Funkcje strzałek automatycznie otrzymują tak zwany zakres leksykalny (mają dostęp do definicji zmiennej w jej bloku zawierającym). Podczas korzystania z funkcji strzałek automatycznie wiąże this
się z miejscem, w którym funkcja strzałki została zdefiniowana w pierwszej kolejności, a kontekst tej funkcji strzałki jest zawarte w nim blok.
Zobacz, jak to działa w praktyce na najprostszych przykładach poniżej.
Przed funkcjami strzałek (domyślnie brak zakresu leksykalnego):
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"
Z funkcjami strzałek (domyślnie zakres leksykalny):
const programming = {
language: "JavaScript",
getLanguage: function() {
return this.language;
}
}
const arrowFunction = () => {
console.log(programming.getLanguage());
}
arrowFunction(); // Output: "JavaScript"