01 Scope nədir?
Scope proqramın hansı hissələrində hansı dəyişənlərə müraciət edə biləcəyinizi müəyyən edir. Bu, JavaScript-də kodun təşkilinin əsas konsepsiyasıdır.
Sadə şəkildə desək, scope sizə deyir ki, kodunuzun müəyyən bir nöqtəsində hansı dəyişənlərə "çata" bilərsiniz.
// Scope nümunəsi
let globalVar = "I'm global";
function myFunction() {
let functionVar = "I'm local to function";
console.log(globalVar); // Əlçatandır ✓
console.log(functionVar); // Əlçatandır ✓
}
myFunction();
console.log(globalVar); // Əlçatandır ✓
console.log(functionVar); // ReferenceError: functionVar is not defined02 Block scope
let və const ilə yaradılan dəyişənlər block scope-a malikdir. Bu o deməkdir ki, onlar yalnız yaradıldıqları blok daxilində mövcuddur.
Blok nədir?
Blok mötərizələr {} ilə əhatə olunmuş kod parçasıdır. Bloklar if, for, while və digər strukturlarda istifadə olunur.
// Blok nümunələri
{
// Bu blok daxilindədir
}
if (true) {
// if bloku
}
for (let i = 0; i < 5; i++) {
// for bloku
}let və const ilə block scope
let və const ilə yaradılan dəyişənlər yalnız yaradıldıqları blok daxilində əlçatandır:
{
let blockLet = "I'm in a block";
const blockConst = "Me too!";
console.log(blockLet); // I'm in a block
console.log(blockConst); // Me too!
}
console.log(blockLet); // ReferenceError: blockLet is not defined
console.log(blockConst); // ReferenceError: blockConst is not definedPraktik nümunələr
Gəlin block scope-un real istifadə hallarına baxaq:
// if blokunda
if (true) {
let message = "Hello from if block";
console.log(message); // Hello from if block
}
// console.log(message); // ReferenceError
// for loopunda
for (let i = 0; i < 3; i++) {
let loopVar = i * 2;
console.log(loopVar); // 0, 2, 4
}
// console.log(i); // ReferenceError
// console.log(loopVar); // ReferenceError03 Function scope
var ilə yaradılan dəyişənlər function scope-a malikdir. Bu o deməkdir ki, onlar bütün funksiyanın daxilində əlçatandır, lakin blok sərhədlərinə riayət etmirlər.
var-ın davranışı
var ilə yaradılan dəyişənlər funksiyanın hər yerindən əlçatandır, blok daxilində yaradılsalar belə:
function testVar() {
var functionScoped = "I'm function scoped";
if (true) {
var alsoFunctionScoped = "Me too!";
console.log(functionScoped); // İşləyir ✓
}
console.log(alsoFunctionScoped); // Hələ də işləyir ✓
}
testVar();
// console.log(functionScoped); // ReferenceErrorvar və let/const müqayisəsi
Gəlin var və let/const arasındakı fərqə baxaq:
// var blokdan kənarda əlçatandır
if (true) {
var varVariable = "I'm var";
let letVariable = "I'm let";
}
console.log(varVariable); // I'm var
console.log(letVariable); // ReferenceError: letVariable is not defined
// Loop dəyişənləri
for (var i = 0; i < 3; i++) {
// loop body
}
console.log(i); // 3
for (let j = 0; j < 3; j++) {
// loop body
}
// console.log(j); // ReferenceError: letVariable is not defined04 Global scope
Hər hansı funksiya və ya blokdan kənarda yaradılan dəyişənlər global scope-dadır. Global dəyişənlərə kodunuzun istənilən yerindən çatmaq olar.
Global dəyişənlər
Global scope-da yaradılan dəyişənlər bütün proqramınızda əlçatandır:
// Global dəyişənlər
let globalLet = "Global with let";
const globalConst = "Global with const";
var globalVar = "Global with var";
function accessGlobals() {
console.log(globalLet); // Əlçatandır
console.log(globalConst); // Əlçatandır
console.log(globalVar); // Əlçatandır
}
accessGlobals();Global obyekt
Brauzerdə global scope window obyektinə, Node.js-də isə global obyektinə bağlıdır:
// Brauzerdə
var globalVar = "I'm on window";
let globalLet = "I'm NOT on window";
console.log(window.globalVar); // I'm on window
console.log(window.globalLet); // undefined
// Global funksiya
function sayHello() {
console.log("Hello!");
}
window.sayHello(); // Hello!05 Lexical scoping
Lexical scoping (həmçinin static scoping kimi tanınır) JavaScript-in scope-ları necə müəyyən etdiyini izah edir. Dəyişənlərin scope-u kodun yazıldığı yerə görə müəyyən olunur.
İç-içə funksiyalar
İçəridəki funksiyalar xaricdəki funksiyanın dəyişənlərinə çata bilər:
function outer() {
let outerVar = "I'm from outer";
function inner() {
let innerVar = "I'm from inner";
console.log(outerVar); // Əlçatandır ✓
console.log(innerVar); // Əlçatandır ✓
}
inner();
// console.log(innerVar); // ReferenceError: innerVar is not defined
}
outer();Scope chain
JavaScript dəyişən axtararkən scope chain-dən istifadə edir:
- Cari scope-da dəyişən axtarılır
- Tapılmazsa, bir səviyyə yuxarı (xarici scope) axtarılır
- Bu proses dəyişən tapılana və ya global scope-a çatana qədər davam edir
- Heç yerdə tapılmazsa, ReferenceError baş verir
let global = "Global scope";
function levelOne() {
let one = "Level 1";
function levelTwo() {
let two = "Level 2";
function levelThree() {
let three = "Level 3";
// Scope chain işləyir
console.log(three); // Səviyyə 3-dən
console.log(two); // Səviyyə 2-dən
console.log(one); // Səviyyə 1-dən
console.log(global); // Global scope-dan
}
levelThree();
}
levelTwo();
}
levelOne();06 Variable shadowing
Variable shadowing daxili scope-da xarici scope-dakı dəyişənlə eyni adda dəyişən yaradarkən baş verir. Daxili dəyişən xarici dəyişəni "kölgələyir".
Shadowing nümunəsi
Eyni adlı müxtəlif scope-larda dəyişənlər yarada bilərik:
let name = "Global";
function greet() {
let name = "Function"; // Global name-i kölgələyir
console.log(name); // Function
if (true) {
let name = "Block"; // Function name-i kölgələyir
console.log(name); // Block
}
console.log(name); // Function
}
greet();
console.log(name); // GlobalShadowing nə zaman baş verir?
- Daxili funksiyada xarici funksiyanın dəyişəni ilə eyni adda dəyişən yaradarkən
- Blokda xarici scope-dakı dəyişənlə eyni adda dəyişən yaradarkən
- Funksiya parametri xarici scope-dakı dəyişənlə eyni adda olanda
07 Hoisting
Hoisting JavaScript-in dəyişən və funksiya bəyannamələrini scope-un yuxarısına "qaldırması" prosesidir. Bu, kodun icrasından əvvəl baş verir.
var hoisting
var ilə yaradılan dəyişənlər hoisted olunur və undefined ilə başlanğıc dəyər alır:
console.log(x); // undefined
var x = 5;
console.log(x); // 5
// Yuxarıdakı kod belə işləyir:
// var x;
// console.log(x); // undefined
// x = 5;
// console.log(x); // 5Funksiya hoisting
Funksiya bəyannamələri (function declarations) tam şəkildə hoisted olunur:
// Funksiya bəyannaməsi hoisted olunur
greet(); // Hello!
function greet() {
console.log("Hello!");
}
// Function expression hoisted olunmur
// sayHi(); // ReferenceError
const sayHi = function() {
console.log("Hi!");
};let və const hoisting
let və const da texniki olaraq hoisted olunur, lakin onlara bəyannamədən əvvəl müraciət etmək mümkün deyil:
// TDZ xətası
console.log(x); // ReferenceError: Cannot access before initialization
let x = 5;
console.log(y); // ReferenceError: Cannot access before initialization
const y = 10;08 Temporal dead zone (TDZ)
Temporal dead zone (TDZ) scope-un başlanğıcından dəyişənin bəyan edilməsinə qədər olan zaman aralığıdır. Bu müddətdə dəyişənə müraciət etmək xəta verir.
TDZ nümunəsi
Gəlin TDZ-nin necə işlədiyinə baxaq:
// TDZ nümunəsi
{
// TDZ başlanğıcı - hələ əlçatan deyil
// console.log(x); // ReferenceError: Cannot access before initialization
// console.log(y); // ReferenceError: Cannot access before initialization
let x = 10; // TDZ sonu - artıq əlçatandır
const y = 20; // TDZ sonu - artıq əlçatandır
console.log(x); // 10
console.log(y); // 20
}TDZ niyə mövcuddur?
- Dəyişənlərin bəyan edilməmişdən əvvəl istifadəsini önləyir
- Kodda səhvləri daha tez aşkar etməyə kömək edir
- Const dəyişənlərinin məntiqini qoruyur (həmişə dəyərlə yaradılmalı)
09 Dəyişənlərin həyat dövrü
Hər dəyişənin JavaScript-də həyat dövrü var: creation (yaradılma), initialization (başlanğıc dəyər), və assignment (dəyər təyin etmə). Bu fazalar var, let və const üçün fərqlidir.
Üç faza
1. Creation (yaradılma)
Dəyişən scope-da qeydə alınır, lakin hələ dəyər almayıb:
- var: undefined ilə initialize olunur
- let/const: initialize olunmur (TDZ başlayır)
2. Initialization (başlanğıc dəyər)
Dəyişənə ilk dəfə dəyər verilir:
- var: avtomatik olaraq undefined alır
- let/const: bəyannamə xəttində initialize olunur (TDZ bitir)
3. Assignment (dəyər təyin etmə)
Dəyişənə yeni dəyər verilir:
- var və let: dəyərlər dəyişdirilə bilər
- const: yalnız bir dəfə, initialization zamanı təyin edilə bilər
Həyat dövrü müqayisəsi
Gəlin var və let/const-ın həyat dövrünü müqayisə edək:
// var vs let/const həyat dövrü
console.log(varVariable); // undefined (hoisted və initialized)
// console.log(letVariable); // ReferenceError (hoisted amma TDZ-də)
var varVariable = "var value";
let letVariable = "let value";
console.log(varVariable); // var value
console.log(letVariable); // let value
// var: creation → initialization (undefined) → assignment
// let: creation (TDZ) → initialization → assignment
// const: creation (TDZ) → initialization və assignment birlikdə
// const yalnız bəyannamə zamanı dəyər ala bilər10 Ən yaxşı təcrübələr
Scope və dəyişənlərlə işləyərkən bu qaydalara əməl edin:
const və let istifadə edin
var-dan istifadə etməyin. const və let daha təhlükəsiz, gözlənilən və block scope-a malikdir. Const-u prioritet verin, yalnız dəyər dəyişməli olduqda let istifadə edin.
var-dan qaçın
var köhnə və problemlidir. Function scope və hoisting davranışı gözlənilməz xətalara səbəb ola bilər. Modern JavaScript kodunda var-a ehtiyac yoxdur.
Dəyişənləri scope-un əvvəlində bəyan edin
Dəyişənləri scope-un yuxarısında bəyan etmək kodu daha oxunaqlı edir və TDZ problemlərinin qarşısını alır.
Scope-u mümkün qədər məhdudlaşdırın
Dəyişənləri ehtiyac duyulduqları ən kiçik scope-da yaradın. Bu ad toqquşmalarının qarşısını alır və kodu daha anlaşıqlı edir.
Shadowing-dən qaçın
Xarici scope-dakı dəyişənlərlə eyni adda dəyişən yaratmayın. Fərqli, aydın adlar istifadə edin.
Xülasə
Təklifiniz var, səhv və ya xəta tapdınız? Zəhmət olmasa bizimlə əlaqə saxlayın.