SlideShare a Scribd company logo
1 of 28
Download to read offline
Lexical Scope,
Function vs. Block Scope,
Hoisting, Scope Closures
DevDuck |
Maciej Cąderek
Fullstack JS Developer @Brainhub
Czym jest scope?
Zestaw reguł
definiujących zakres widoczności
(dostępności) zmiennych.
Lexical scope
● Zasięg zmiennych jest określany na podstawie ich umiejscowienia w kodzie i kontekstu
w jakim się znajdują
● Scope zmiennych jest stały, określany na etapie kompilacji (wczesne wiązanie)
● W JavaScripcie scope jest określany poprzez funkcje (ES5) oraz bloki kodu (ES6)
Lexical scope
● Kod wewnątrz scope'a ma dostęp do zmiennych zadeklarowanych w scopie
zewnętrznym
● W pierwszej kolejności wykorzystywane są zmienne w lokalnym zasięgu, następnie
kolejne poziomy zagnieżdzenia scope'a
const a = 1;
const b = 2;
function x() {
const b = 3;
console.log(a); // => 1
console.log(b); // => 3
}
Function scope
● Jedyny dostępny sposób określania zasięgu zmiennych w ES5
● Najmniejszą jednostką scope'a jest funkcja
● Mechanizm specyficzny dla JavaScriptu
● Do deklaracji zmiennej wewnątrz scope'a służy słowo kluczowe var
● Użycie var w ES6+ jest niezalecane
Czym jest hoisting?
● Dwie fazy przetwarzania kodu - kompilacja i wykonanie
var a = 1;
var myFunction = function () {
// code...
};
function myOtherFunction() {
// code...
}
myFunction();
myOtherFunction();
Czym jest hoisting?
● W fazie kompilacji wczytywane są
jedynie deklaracje (zarówno
zmiennych jak i funkcji)
var a;
var myFunction;
function myOtherFunction() {
// code...
}
a = 1;
myFunction = function () {
// code...
};
myFunction();
myOtherFunction();
● W fazie wykonywania kodu
przetwarzane są pozostałe instrukcje -
przypisania zmiennych, wywołania
funkcji itp
Hoisting - minusy
● Hoisting deklaracji zmiennych może prowadzić do nieczytelnego, nieoczywistego kodu
var a = 1;
function doSomeStuff() {
a = 2;
var a = 3;
return a;
}
console.log(doSomeStuff()); // => 3
console.log(a); // => 1
Hoisting - plusy
● Hoisting funkcji pozwala na czytelniejszy zapis kodu - funkcje zawierające główną
logikę można umieścić przed funkcjami pomocniczymi
function doSomeStuff() {
runHelper();
// other code...
}
function runHelper() {
// code...
}
var
● Ze względu na hoisting wszystkie deklaracje powinny znajdować się na początku
funkcji
● Możliwa ponowna deklaracja zmiennej
function doSomeStuff() {
// all declarations with optional assigments:
var a;
var b = 'something';
var c = 'something';
// rest of the code...
}
Block scope
● Sposób określania zasięgu zmiennych dostępny od ES6
● Najmniejszą jednostką scope'a jest blok kodu reprezentowany przez nawiasy
klamrowe
● Mechanizm znany z wiekszości języków programowania
● Do deklaracji zmiennej wewnątrz block scope'a służą słowa kluczowe let oraz const
let & const
● Brak możliwości ponownej deklaracji zmiennej
● Dodatkowo const nie pozwala na ponowne przypisanie wartości do
zmiennej (nie mylić z modyfikacją typów złożonych)
● Deklaracje zmiennych powinny znajdować się jak najbliżej ich
wykorzystania
Kiedy var, let a kiedy const?
● Zasada: zawsze preferuj niemutowalny kod
● Dlaczego? Kod jest łatwiejszy w zrozumieniu i debugowaniu
● W ES6+ var nie powinno być nigdy stosowane
● const powinien stanowić domyślny wybór
● let powinien być stosowany tylko wtedy, gdy wartość zmiennej jest ponownie
przypisywana (np. licznik pętli)
Zalety block scope
● Brak hoistingu - mniejsza podatność na błędy
function changeStyle() {
const header = document.getElementById('header');
const article = document.getElementById('article');
const footer = document.getElementById('footer');
const mainColor = '#FF0000';
const accentColor = '#928c00';
header.style.backgroundColor = mainColor;
header.style.color = accentColor;
footer.style.backgroundColor = accentColor;
}
Zalety block scope
● Lepsza organzacja kodu - deklaracje zmiennych w miejscu ich użycia
function changeStyle() {
const mainColor = '#FF0000';
const header = document.getElementById('header');
const accentColor = '#928c00';
header.style.backgroundColor = mainColor;
header.style.color = accentColor;
const footer = document.getElementById('footer');
footer.style.backgroundColor = mainColor;
}
Zalety block scope
● Ograniczenie zasięgu zmiennych do wymaganego minimum
function changeStyle() {
const mainColor = '#FF0000';
{
const header = document.getElementById('header');
const accentColor = '#928c00';
header.style.backgroundColor = mainColor;
header.style.color = accentColor;
}
{
const footer = document.getElementById('footer');
footer.style.backgroundColor = mainColor;
}
}
Symulowanie bock scope'a w ES5
● Do symulowania block scope'a służy IIFE ( immediately-invoked function expression )
function changeRestStyle() {
var mainColor = '#FF0000';
(function () {
var header = document.getElementById('header');
var accentColor = '#928c00';
header.style.backgroundColor = mainColor;
header.style.color = accentColor;
}());
(function () {
var footer = document.getElementById('footer');
footer.style.backgroundColor = mainColor;
})();
}
First-class functions
● Funkcje w JavaScript są obiektami pierwszej kategorii - mogą być traktowane jak
wartości i przypisywane do zmiennych oraz stanowić elementy tablic i pola obiektów,
● Funkcje mogą być przekazywane jako argumenty do innych funkcji, mogą także
stanowić wartość zwracaną z funkcji
● Funkcje, które przyjmuja inną funkcje jako argument lub zwracają inną funkcję są
nazywane funkcjami wyższego rzedu (higher order functions)
● Funkcje mogą byc dowolnie zagnieżdżane, każda funkcja tworzy nowy scope
Czym jest domknięcie (closure)?
● Domknięcie to zapis w pamięci silnika, przechowujący funkcję wraz z jej środowiskiem
● Środowisko funkcji stanowią wszystkie zmienne zadeklarowane w scope otaczającym
funkcję, które zostały wewnątrz niej użyte
● Funkcja ma dostęp do swojego lexical scope’a nawet jeśli jest wywoływana poza
swoim scopem
● Domknięcie jest tworzone w miejscu deklaracji funkcji
Podstawowy przykład domknięcia
const name = 'Maciek';
function greet() {
return `Hello, my name is ${name}.`;
}
const result = greet(); // => "Hello, my name is Maciek."
Prosta funkcja wyższego rzędu
function createGreet() {
const name = 'Maciek';
return function() {
return `Hello, my name is ${name}.`;
};
}
const greet = createGreet();
const result = greet(); // => "Hello, my name is Maciek."
Factory function
function createPerson(name) {
const species = 'Homo Sapiens';
return {
showDescription() {
return `Person is a ${species} named ${name}.`;
},
};
}
const john = createPerson('John');
john.showDescription(); // => "Person is a Homo Sapiens named John."
Module pattern (ES5)
var calculator = function () {
function add(a, b) {
return a + b;
}
function square(a) {
return a * a;
}
function sumOfSquares(a, b) {
return add(aquare(a), square(b));
}
return {
sumOfSquares: sumOfSquares,
};
}();
Partial application
function partial(fn, ...parts) {
return function (...rest) {
return fn.apply(null, [...parts, ...rest]);
};
}
function add(...args) {
return args.reduce(function (prev, next) {
return prev + next;
});
};
const addFive = partial(add, 5);
const addEleven = partial(add, 3, 8);
const result1 = addFive(7); // => 12
const result2 = addEleven(3, 6); // => 20
Partial application (arrow functions)
const partial = (fn, ...parts) =>
(...rest) => fn.apply(null, [...parts, ...rest]);
const add = (...args) =>
args.reduce((prev, next) => prev + next);
const addFive = partial(add, 5);
const addEleven = partial(add, 3, 8);
const result1 = addFive(7); // => 12
const result2 = addEleven(3, 6); // => 20
Podsumowanie
● Twórz prosty, modularny, wolny od “magii” kod
● Ograniczaj ruchome części w kodzie, używaj const gdzie to tylko możliwe
● Ograniczaj zakres widoczności zmiennych, organizuj kod w precyzyjne scope'y
● Ukrywaj detale implementacyjne - jedną z metod jest użycie domknięć
● Twórz łatwy w ponownym wykorzystaniu, deklaratywny kod - wykorzystuj zalety funkcji
wyższego rzędu i domknięć
Dziękuję za uwagę ;)
maciej@brainhub.pl
brainhub.pl

More Related Content

What's hot

Znaki mocy dla laików – Programowanie funkcyjne w JavaScript
Znaki mocy dla laików – Programowanie funkcyjne w JavaScriptZnaki mocy dla laików – Programowanie funkcyjne w JavaScript
Znaki mocy dla laików – Programowanie funkcyjne w JavaScriptThe Software House
 
Objective C
Objective CObjective C
Objective Ckonryd
 
Python szybki start
Python   szybki startPython   szybki start
Python szybki startSages
 
Professional Javascript for Developers
Professional  Javascript for DevelopersProfessional  Javascript for Developers
Professional Javascript for DevelopersRule_Financial
 
Bash 1 ----- wykład2i3
Bash 1   -----     wykład2i3Bash 1   -----     wykład2i3
Bash 1 ----- wykład2i3kkk112
 

What's hot (7)

Znaki mocy dla laików – Programowanie funkcyjne w JavaScript
Znaki mocy dla laików – Programowanie funkcyjne w JavaScriptZnaki mocy dla laików – Programowanie funkcyjne w JavaScript
Znaki mocy dla laików – Programowanie funkcyjne w JavaScript
 
Objective C
Objective CObjective C
Objective C
 
Python szybki start
Python   szybki startPython   szybki start
Python szybki start
 
Php P.Jar
Php P.JarPhp P.Jar
Php P.Jar
 
Professional Javascript for Developers
Professional  Javascript for DevelopersProfessional  Javascript for Developers
Professional Javascript for Developers
 
Php5
Php5Php5
Php5
 
Bash 1 ----- wykład2i3
Bash 1   -----     wykład2i3Bash 1   -----     wykład2i3
Bash 1 ----- wykład2i3
 

Viewers also liked

All you need to know about Callbacks, Promises, Generators
All you need to know about Callbacks, Promises, GeneratorsAll you need to know about Callbacks, Promises, Generators
All you need to know about Callbacks, Promises, GeneratorsBrainhub
 
Why and How You Should Move from PHP to Node.js
Why and How You Should Move from PHP to Node.jsWhy and How You Should Move from PHP to Node.js
Why and How You Should Move from PHP to Node.jsBrainhub
 
Technologia, a Startup - Brainhub
Technologia, a Startup - BrainhubTechnologia, a Startup - Brainhub
Technologia, a Startup - BrainhubBrainhub
 
Wprowadzenie do React
Wprowadzenie do ReactWprowadzenie do React
Wprowadzenie do ReactBrainhub
 
How should you React to Redux
How should you React to ReduxHow should you React to Redux
How should you React to ReduxBrainhub
 
JavaScript and Desktop Apps - Introduction to Electron
JavaScript and Desktop Apps - Introduction to ElectronJavaScript and Desktop Apps - Introduction to Electron
JavaScript and Desktop Apps - Introduction to ElectronBrainhub
 
Introduction to GraphQL
Introduction to GraphQLIntroduction to GraphQL
Introduction to GraphQLBrainhub
 
1 defining marketing for the 21st century
1 defining marketing for the 21st century1 defining marketing for the 21st century
1 defining marketing for the 21st centurySaumitra Gupta
 
Marketing jitendra singh
Marketing jitendra singhMarketing jitendra singh
Marketing jitendra singhJitendra Singh
 
Marketing meaning, definition, scope
Marketing  meaning, definition, scopeMarketing  meaning, definition, scope
Marketing meaning, definition, scopeVikash Kumar Bibhakar
 
The nature, scope and function of school administration 2
The nature, scope and function of school administration 2The nature, scope and function of school administration 2
The nature, scope and function of school administration 2Ramil Polintan
 

Viewers also liked (13)

All you need to know about Callbacks, Promises, Generators
All you need to know about Callbacks, Promises, GeneratorsAll you need to know about Callbacks, Promises, Generators
All you need to know about Callbacks, Promises, Generators
 
Why and How You Should Move from PHP to Node.js
Why and How You Should Move from PHP to Node.jsWhy and How You Should Move from PHP to Node.js
Why and How You Should Move from PHP to Node.js
 
Technologia, a Startup - Brainhub
Technologia, a Startup - BrainhubTechnologia, a Startup - Brainhub
Technologia, a Startup - Brainhub
 
Wprowadzenie do React
Wprowadzenie do ReactWprowadzenie do React
Wprowadzenie do React
 
How should you React to Redux
How should you React to ReduxHow should you React to Redux
How should you React to Redux
 
JavaScript and Desktop Apps - Introduction to Electron
JavaScript and Desktop Apps - Introduction to ElectronJavaScript and Desktop Apps - Introduction to Electron
JavaScript and Desktop Apps - Introduction to Electron
 
Introduction to GraphQL
Introduction to GraphQLIntroduction to GraphQL
Introduction to GraphQL
 
1 defining marketing for the 21st century
1 defining marketing for the 21st century1 defining marketing for the 21st century
1 defining marketing for the 21st century
 
Marketing jitendra singh
Marketing jitendra singhMarketing jitendra singh
Marketing jitendra singh
 
M m intrdn
M m intrdnM m intrdn
M m intrdn
 
Marketing meaning, definition, scope
Marketing  meaning, definition, scopeMarketing  meaning, definition, scope
Marketing meaning, definition, scope
 
MARKETING FUNCTIONS
MARKETING FUNCTIONSMARKETING FUNCTIONS
MARKETING FUNCTIONS
 
The nature, scope and function of school administration 2
The nature, scope and function of school administration 2The nature, scope and function of school administration 2
The nature, scope and function of school administration 2
 

Similar to Lexical scope, function vs. block scope, hoisting, scope closures

Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPLaravel Poland MeetUp
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychSKN Shader
 
Angular restmod – wygodny sposób na komunikację z API
Angular restmod – wygodny sposób na komunikację z APIAngular restmod – wygodny sposób na komunikację z API
Angular restmod – wygodny sposób na komunikację z APIThe Software House
 
Intro to JavaScript | Wstęp do programowania w Java Script | DreamLab Academy #4
Intro to JavaScript | Wstęp do programowania w Java Script | DreamLab Academy #4Intro to JavaScript | Wstęp do programowania w Java Script | DreamLab Academy #4
Intro to JavaScript | Wstęp do programowania w Java Script | DreamLab Academy #4DreamLab
 
Modularny JavaScript - meet.js
Modularny JavaScript - meet.jsModularny JavaScript - meet.js
Modularny JavaScript - meet.jsPatryk Jar
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaMaciej Ziarko
 
Angular 4 pragmatycznie
Angular 4 pragmatycznieAngular 4 pragmatycznie
Angular 4 pragmatycznieSages
 
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.Semihalf
 
TWIG - niezłe widoki dla PHP
TWIG - niezłe widoki dla PHPTWIG - niezłe widoki dla PHP
TWIG - niezłe widoki dla PHPPiotr Gabryjeluk
 
AngularJS Warsaw #4 - Dariusz Kalbarczyk "Controller as"
AngularJS Warsaw #4 - Dariusz Kalbarczyk "Controller as"AngularJS Warsaw #4 - Dariusz Kalbarczyk "Controller as"
AngularJS Warsaw #4 - Dariusz Kalbarczyk "Controller as"Dariusz Kalbarczyk
 
Architektura mikrokontrolera pisana słowem.
Architektura mikrokontrolera pisana słowem.Architektura mikrokontrolera pisana słowem.
Architektura mikrokontrolera pisana słowem.Semihalf
 
Podstawy JavaScript | DreamLab Academy #7
Podstawy JavaScript | DreamLab Academy #7Podstawy JavaScript | DreamLab Academy #7
Podstawy JavaScript | DreamLab Academy #7DreamLab
 
Testy API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięciTesty API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięciThe Software House
 

Similar to Lexical scope, function vs. block scope, hoisting, scope closures (20)

Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHP
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
 
Kickoff to Node.js
Kickoff to Node.jsKickoff to Node.js
Kickoff to Node.js
 
Torquebox
TorqueboxTorquebox
Torquebox
 
Angular restmod – wygodny sposób na komunikację z API
Angular restmod – wygodny sposób na komunikację z APIAngular restmod – wygodny sposób na komunikację z API
Angular restmod – wygodny sposób na komunikację z API
 
JavaScript, Moduły
JavaScript, ModułyJavaScript, Moduły
JavaScript, Moduły
 
Intro to JavaScript | Wstęp do programowania w Java Script | DreamLab Academy #4
Intro to JavaScript | Wstęp do programowania w Java Script | DreamLab Academy #4Intro to JavaScript | Wstęp do programowania w Java Script | DreamLab Academy #4
Intro to JavaScript | Wstęp do programowania w Java Script | DreamLab Academy #4
 
Angular Restmod
Angular RestmodAngular Restmod
Angular Restmod
 
Modularny JavaScript - meet.js
Modularny JavaScript - meet.jsModularny JavaScript - meet.js
Modularny JavaScript - meet.js
 
Mongodb with Rails
Mongodb with RailsMongodb with Rails
Mongodb with Rails
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
 
Angular 4 pragmatycznie
Angular 4 pragmatycznieAngular 4 pragmatycznie
Angular 4 pragmatycznie
 
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
 
TWIG - niezłe widoki dla PHP
TWIG - niezłe widoki dla PHPTWIG - niezłe widoki dla PHP
TWIG - niezłe widoki dla PHP
 
AngularJS Warsaw #4 - Dariusz Kalbarczyk "Controller as"
AngularJS Warsaw #4 - Dariusz Kalbarczyk "Controller as"AngularJS Warsaw #4 - Dariusz Kalbarczyk "Controller as"
AngularJS Warsaw #4 - Dariusz Kalbarczyk "Controller as"
 
Architektura mikrokontrolera pisana słowem.
Architektura mikrokontrolera pisana słowem.Architektura mikrokontrolera pisana słowem.
Architektura mikrokontrolera pisana słowem.
 
Podstawy JavaScript | DreamLab Academy #7
Podstawy JavaScript | DreamLab Academy #7Podstawy JavaScript | DreamLab Academy #7
Podstawy JavaScript | DreamLab Academy #7
 
Testy API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięciTesty API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięci
 
react-pl.pdf
react-pl.pdfreact-pl.pdf
react-pl.pdf
 
Behat
BehatBehat
Behat
 

More from Brainhub

AWS – jak rozpocząć przygodę z chmurą?
AWS – jak rozpocząć przygodę z chmurą?AWS – jak rozpocząć przygodę z chmurą?
AWS – jak rozpocząć przygodę z chmurą?Brainhub
 
Konfiguracja GitLab CI/CD pipelines od podstaw
Konfiguracja GitLab CI/CD pipelines od podstawKonfiguracja GitLab CI/CD pipelines od podstaw
Konfiguracja GitLab CI/CD pipelines od podstawBrainhub
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?Brainhub
 
Solid.js - następca Reacta?
Solid.js - następca Reacta?Solid.js - następca Reacta?
Solid.js - następca Reacta?Brainhub
 
Struktury algebraiczne w JavaScripcie
Struktury algebraiczne w JavaScripcieStruktury algebraiczne w JavaScripcie
Struktury algebraiczne w JavaScripcieBrainhub
 
WebAssembly - czy dzisiaj mi się to przyda do pracy?
WebAssembly - czy dzisiaj mi się to przyda do pracy?WebAssembly - czy dzisiaj mi się to przyda do pracy?
WebAssembly - czy dzisiaj mi się to przyda do pracy?Brainhub
 
Ewoluowanie neuronowych mózgów w JavaScript, wielowątkowo!
Ewoluowanie neuronowych mózgów w JavaScript, wielowątkowo!Ewoluowanie neuronowych mózgów w JavaScript, wielowątkowo!
Ewoluowanie neuronowych mózgów w JavaScript, wielowątkowo!Brainhub
 
Go home TypeScript, you're drunk!
Go home TypeScript, you're drunk!Go home TypeScript, you're drunk!
Go home TypeScript, you're drunk!Brainhub
 
How I taught the messenger to tell lame jokes
How I taught the messenger to tell lame jokesHow I taught the messenger to tell lame jokes
How I taught the messenger to tell lame jokesBrainhub
 
The hunt of the unicorn, to capture productivity
The hunt of the unicorn, to capture productivityThe hunt of the unicorn, to capture productivity
The hunt of the unicorn, to capture productivityBrainhub
 
TDD in the wild
TDD in the wildTDD in the wild
TDD in the wildBrainhub
 
WebAssembly - kolejny buzzword, czy (r)ewolucja?
WebAssembly - kolejny buzzword, czy (r)ewolucja?WebAssembly - kolejny buzzword, czy (r)ewolucja?
WebAssembly - kolejny buzzword, czy (r)ewolucja?Brainhub
 
React performance
React performanceReact performance
React performanceBrainhub
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSBrainhub
 
React Native in a nutshell
React Native in a nutshellReact Native in a nutshell
React Native in a nutshellBrainhub
 
Ant Colony Optimization (Heuristic algorithms & Swarm intelligence)
Ant Colony Optimization (Heuristic algorithms & Swarm intelligence)Ant Colony Optimization (Heuristic algorithms & Swarm intelligence)
Ant Colony Optimization (Heuristic algorithms & Swarm intelligence)Brainhub
 

More from Brainhub (16)

AWS – jak rozpocząć przygodę z chmurą?
AWS – jak rozpocząć przygodę z chmurą?AWS – jak rozpocząć przygodę z chmurą?
AWS – jak rozpocząć przygodę z chmurą?
 
Konfiguracja GitLab CI/CD pipelines od podstaw
Konfiguracja GitLab CI/CD pipelines od podstawKonfiguracja GitLab CI/CD pipelines od podstaw
Konfiguracja GitLab CI/CD pipelines od podstaw
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?
 
Solid.js - następca Reacta?
Solid.js - następca Reacta?Solid.js - następca Reacta?
Solid.js - następca Reacta?
 
Struktury algebraiczne w JavaScripcie
Struktury algebraiczne w JavaScripcieStruktury algebraiczne w JavaScripcie
Struktury algebraiczne w JavaScripcie
 
WebAssembly - czy dzisiaj mi się to przyda do pracy?
WebAssembly - czy dzisiaj mi się to przyda do pracy?WebAssembly - czy dzisiaj mi się to przyda do pracy?
WebAssembly - czy dzisiaj mi się to przyda do pracy?
 
Ewoluowanie neuronowych mózgów w JavaScript, wielowątkowo!
Ewoluowanie neuronowych mózgów w JavaScript, wielowątkowo!Ewoluowanie neuronowych mózgów w JavaScript, wielowątkowo!
Ewoluowanie neuronowych mózgów w JavaScript, wielowątkowo!
 
Go home TypeScript, you're drunk!
Go home TypeScript, you're drunk!Go home TypeScript, you're drunk!
Go home TypeScript, you're drunk!
 
How I taught the messenger to tell lame jokes
How I taught the messenger to tell lame jokesHow I taught the messenger to tell lame jokes
How I taught the messenger to tell lame jokes
 
The hunt of the unicorn, to capture productivity
The hunt of the unicorn, to capture productivityThe hunt of the unicorn, to capture productivity
The hunt of the unicorn, to capture productivity
 
TDD in the wild
TDD in the wildTDD in the wild
TDD in the wild
 
WebAssembly - kolejny buzzword, czy (r)ewolucja?
WebAssembly - kolejny buzzword, czy (r)ewolucja?WebAssembly - kolejny buzzword, czy (r)ewolucja?
WebAssembly - kolejny buzzword, czy (r)ewolucja?
 
React performance
React performanceReact performance
React performance
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
React Native in a nutshell
React Native in a nutshellReact Native in a nutshell
React Native in a nutshell
 
Ant Colony Optimization (Heuristic algorithms & Swarm intelligence)
Ant Colony Optimization (Heuristic algorithms & Swarm intelligence)Ant Colony Optimization (Heuristic algorithms & Swarm intelligence)
Ant Colony Optimization (Heuristic algorithms & Swarm intelligence)
 

Lexical scope, function vs. block scope, hoisting, scope closures

  • 1. Lexical Scope, Function vs. Block Scope, Hoisting, Scope Closures DevDuck |
  • 2. Maciej Cąderek Fullstack JS Developer @Brainhub
  • 3. Czym jest scope? Zestaw reguł definiujących zakres widoczności (dostępności) zmiennych.
  • 4. Lexical scope ● Zasięg zmiennych jest określany na podstawie ich umiejscowienia w kodzie i kontekstu w jakim się znajdują ● Scope zmiennych jest stały, określany na etapie kompilacji (wczesne wiązanie) ● W JavaScripcie scope jest określany poprzez funkcje (ES5) oraz bloki kodu (ES6)
  • 5. Lexical scope ● Kod wewnątrz scope'a ma dostęp do zmiennych zadeklarowanych w scopie zewnętrznym ● W pierwszej kolejności wykorzystywane są zmienne w lokalnym zasięgu, następnie kolejne poziomy zagnieżdzenia scope'a const a = 1; const b = 2; function x() { const b = 3; console.log(a); // => 1 console.log(b); // => 3 }
  • 6. Function scope ● Jedyny dostępny sposób określania zasięgu zmiennych w ES5 ● Najmniejszą jednostką scope'a jest funkcja ● Mechanizm specyficzny dla JavaScriptu ● Do deklaracji zmiennej wewnątrz scope'a służy słowo kluczowe var ● Użycie var w ES6+ jest niezalecane
  • 7. Czym jest hoisting? ● Dwie fazy przetwarzania kodu - kompilacja i wykonanie var a = 1; var myFunction = function () { // code... }; function myOtherFunction() { // code... } myFunction(); myOtherFunction();
  • 8. Czym jest hoisting? ● W fazie kompilacji wczytywane są jedynie deklaracje (zarówno zmiennych jak i funkcji) var a; var myFunction; function myOtherFunction() { // code... } a = 1; myFunction = function () { // code... }; myFunction(); myOtherFunction(); ● W fazie wykonywania kodu przetwarzane są pozostałe instrukcje - przypisania zmiennych, wywołania funkcji itp
  • 9. Hoisting - minusy ● Hoisting deklaracji zmiennych może prowadzić do nieczytelnego, nieoczywistego kodu var a = 1; function doSomeStuff() { a = 2; var a = 3; return a; } console.log(doSomeStuff()); // => 3 console.log(a); // => 1
  • 10. Hoisting - plusy ● Hoisting funkcji pozwala na czytelniejszy zapis kodu - funkcje zawierające główną logikę można umieścić przed funkcjami pomocniczymi function doSomeStuff() { runHelper(); // other code... } function runHelper() { // code... }
  • 11. var ● Ze względu na hoisting wszystkie deklaracje powinny znajdować się na początku funkcji ● Możliwa ponowna deklaracja zmiennej function doSomeStuff() { // all declarations with optional assigments: var a; var b = 'something'; var c = 'something'; // rest of the code... }
  • 12. Block scope ● Sposób określania zasięgu zmiennych dostępny od ES6 ● Najmniejszą jednostką scope'a jest blok kodu reprezentowany przez nawiasy klamrowe ● Mechanizm znany z wiekszości języków programowania ● Do deklaracji zmiennej wewnątrz block scope'a służą słowa kluczowe let oraz const
  • 13. let & const ● Brak możliwości ponownej deklaracji zmiennej ● Dodatkowo const nie pozwala na ponowne przypisanie wartości do zmiennej (nie mylić z modyfikacją typów złożonych) ● Deklaracje zmiennych powinny znajdować się jak najbliżej ich wykorzystania
  • 14. Kiedy var, let a kiedy const? ● Zasada: zawsze preferuj niemutowalny kod ● Dlaczego? Kod jest łatwiejszy w zrozumieniu i debugowaniu ● W ES6+ var nie powinno być nigdy stosowane ● const powinien stanowić domyślny wybór ● let powinien być stosowany tylko wtedy, gdy wartość zmiennej jest ponownie przypisywana (np. licznik pętli)
  • 15. Zalety block scope ● Brak hoistingu - mniejsza podatność na błędy function changeStyle() { const header = document.getElementById('header'); const article = document.getElementById('article'); const footer = document.getElementById('footer'); const mainColor = '#FF0000'; const accentColor = '#928c00'; header.style.backgroundColor = mainColor; header.style.color = accentColor; footer.style.backgroundColor = accentColor; }
  • 16. Zalety block scope ● Lepsza organzacja kodu - deklaracje zmiennych w miejscu ich użycia function changeStyle() { const mainColor = '#FF0000'; const header = document.getElementById('header'); const accentColor = '#928c00'; header.style.backgroundColor = mainColor; header.style.color = accentColor; const footer = document.getElementById('footer'); footer.style.backgroundColor = mainColor; }
  • 17. Zalety block scope ● Ograniczenie zasięgu zmiennych do wymaganego minimum function changeStyle() { const mainColor = '#FF0000'; { const header = document.getElementById('header'); const accentColor = '#928c00'; header.style.backgroundColor = mainColor; header.style.color = accentColor; } { const footer = document.getElementById('footer'); footer.style.backgroundColor = mainColor; } }
  • 18. Symulowanie bock scope'a w ES5 ● Do symulowania block scope'a służy IIFE ( immediately-invoked function expression ) function changeRestStyle() { var mainColor = '#FF0000'; (function () { var header = document.getElementById('header'); var accentColor = '#928c00'; header.style.backgroundColor = mainColor; header.style.color = accentColor; }()); (function () { var footer = document.getElementById('footer'); footer.style.backgroundColor = mainColor; })(); }
  • 19. First-class functions ● Funkcje w JavaScript są obiektami pierwszej kategorii - mogą być traktowane jak wartości i przypisywane do zmiennych oraz stanowić elementy tablic i pola obiektów, ● Funkcje mogą być przekazywane jako argumenty do innych funkcji, mogą także stanowić wartość zwracaną z funkcji ● Funkcje, które przyjmuja inną funkcje jako argument lub zwracają inną funkcję są nazywane funkcjami wyższego rzedu (higher order functions) ● Funkcje mogą byc dowolnie zagnieżdżane, każda funkcja tworzy nowy scope
  • 20. Czym jest domknięcie (closure)? ● Domknięcie to zapis w pamięci silnika, przechowujący funkcję wraz z jej środowiskiem ● Środowisko funkcji stanowią wszystkie zmienne zadeklarowane w scope otaczającym funkcję, które zostały wewnątrz niej użyte ● Funkcja ma dostęp do swojego lexical scope’a nawet jeśli jest wywoływana poza swoim scopem ● Domknięcie jest tworzone w miejscu deklaracji funkcji
  • 21. Podstawowy przykład domknięcia const name = 'Maciek'; function greet() { return `Hello, my name is ${name}.`; } const result = greet(); // => "Hello, my name is Maciek."
  • 22. Prosta funkcja wyższego rzędu function createGreet() { const name = 'Maciek'; return function() { return `Hello, my name is ${name}.`; }; } const greet = createGreet(); const result = greet(); // => "Hello, my name is Maciek."
  • 23. Factory function function createPerson(name) { const species = 'Homo Sapiens'; return { showDescription() { return `Person is a ${species} named ${name}.`; }, }; } const john = createPerson('John'); john.showDescription(); // => "Person is a Homo Sapiens named John."
  • 24. Module pattern (ES5) var calculator = function () { function add(a, b) { return a + b; } function square(a) { return a * a; } function sumOfSquares(a, b) { return add(aquare(a), square(b)); } return { sumOfSquares: sumOfSquares, }; }();
  • 25. Partial application function partial(fn, ...parts) { return function (...rest) { return fn.apply(null, [...parts, ...rest]); }; } function add(...args) { return args.reduce(function (prev, next) { return prev + next; }); }; const addFive = partial(add, 5); const addEleven = partial(add, 3, 8); const result1 = addFive(7); // => 12 const result2 = addEleven(3, 6); // => 20
  • 26. Partial application (arrow functions) const partial = (fn, ...parts) => (...rest) => fn.apply(null, [...parts, ...rest]); const add = (...args) => args.reduce((prev, next) => prev + next); const addFive = partial(add, 5); const addEleven = partial(add, 3, 8); const result1 = addFive(7); // => 12 const result2 = addEleven(3, 6); // => 20
  • 27. Podsumowanie ● Twórz prosty, modularny, wolny od “magii” kod ● Ograniczaj ruchome części w kodzie, używaj const gdzie to tylko możliwe ● Ograniczaj zakres widoczności zmiennych, organizuj kod w precyzyjne scope'y ● Ukrywaj detale implementacyjne - jedną z metod jest użycie domknięć ● Twórz łatwy w ponownym wykorzystaniu, deklaratywny kod - wykorzystuj zalety funkcji wyższego rzędu i domknięć
  • 28. Dziękuję za uwagę ;) maciej@brainhub.pl brainhub.pl