آکادمی بنو/آموزش JavaScript

مفاهیم پیشرفته جاوااسکریپت

بهنام نوبخت · ۱۴۰۵/۷/۱۱

تا اینجا با بخش بزرگی از Syntax و قابلیت‌های جاوااسکریپت آشنا شدیم؛ از متغیرها، شرط‌ها و حلقه‌ها گرفته تا Function، Array، Object، DOM، Event، Form، Regular Expression و امکانات مدرن ES6.

اما برای اینکه بتوانیم در پروژه‌های واقعی جاوااسکریپت کدهای بهتر و قابل‌اعتمادتری بنویسیم، فقط دانستن Syntax کافی نیست.

باید بدانیم جاوااسکریپت چگونه کدها را اجرا می‌کند و مفاهیمی مانند Scope، Execution Context، Hoisting، Closure، this، Prototype و Call Stack چگونه کار می‌کنند.

این مفاهیم در ابتدا ممکن است کمی پیچیده به نظر برسند، اما اگر آن‌ها را مرحله‌به‌مرحله یاد بگیریم، بسیاری از رفتارهایی که قبلاً در جاوااسکریپت عجیب به نظر می‌رسیدند، قابل درک خواهند شد.

در این مقاله با مفاهیم زیر آشنا می‌شویم:

  • Scope

  • Global Scope

  • Function Scope

  • Block Scope

  • Lexical Scope

  • Execution Context

  • Call Stack

  • Hoisting

  • Temporal Dead Zone

  • Closure

  • this

  • Prototype

  • Prototype Chain

  • Constructor Function

  • new

  • Shallow Copy و Reference

  • Immutability

  • Garbage Collection

  • و چند نکته مهم درباره نحوه اجرای جاوااسکریپت

چرا مفاهیم پیشرفته جاوااسکریپت مهم هستند؟

فرض کنید کد زیر را اجرا کنیم:

console.log(name);

var name = "Ali";

ممکن است انتظار داشته باشیم جاوااسکریپت خطا بدهد، اما نتیجه:

undefined

خواهد بود.

اما اگر بنویسیم:

console.log(name);

let name = "Ali";

خطا دریافت می‌کنیم.

چرا؟

پاسخ این سؤال به مفاهیمی مانند Hoisting، Scope و Temporal Dead Zone مربوط است.

Scope چیست؟

Scope مشخص می‌کند یک متغیر در کدام قسمت از برنامه قابل دسترسی است.

مثلاً:

const name = "Ali";

console.log(name);

چون متغیر در سطح بالای برنامه تعریف شده است، از همان محدوده قابل دسترسی است.

Global Scope

اگر متغیری خارج از Function و Block تعریف شود، معمولاً در محدوده‌ای قرار می‌گیرد که به آن Global Scope می‌گوییم.

مثلاً:

const appName = "My App";

function showAppName() {

    console.log(appName);

}

showAppName();

تابع می‌تواند به appName دسترسی داشته باشد.

Function Scope

متغیری که با var داخل یک Function تعریف شود، در محدوده همان Function قرار دارد.

مثلاً:

function test() {

    var message = "Hello";

    console.log(message);

}

test();

اما:

console.log(message);

خطا ایجاد می‌کند، زیرا message داخل Function تعریف شده است.

Block Scope

let و const دارای Block Scope هستند.

مثلاً:

if (true) {

    const message = "Hello";

    console.log(message);

}

اما خارج از Block:

console.log(message);

به message دسترسی نداریم.

Block چیست؟

ساختارهایی مانند:

if (condition) {
}

یا:

for (...) {
}

دارای Block هستند.

همچنین می‌توانیم یک Block مستقل داشته باشیم:

{
    let value = 10;

    console.log(value);
}

تفاوت var و let در Scope

مثال:

if (true) {

    var a = 10;
    let b = 20;

}

console.log(a);
console.log(b);

a با var خارج از Block نیز قابل دسترسی است.

اما b با let فقط داخل Block قابل دسترسی است.

به همین دلیل در کدهای مدرن جاوااسکریپت معمولاً استفاده از let و const نسبت به var ترجیح داده می‌شود.

Lexical Scope

جاوااسکریپت از Lexical Scope استفاده می‌کند.

یعنی محدوده دسترسی متغیرها بر اساس محل نوشته شدن کد مشخص می‌شود.

مثلاً:

const name = "Ali";

function outer() {

    const age = 25;

    function inner() {

        console.log(name);
        console.log(age);

    }

    inner();
}

outer();

تابع inner می‌تواند به متغیرهای محدوده خودش و محدوده‌های بیرونی دسترسی داشته باشد.

Scope Chain

اگر جاوااسکریپت متغیری را در Scope فعلی پیدا نکند، به Scope بیرونی مراجعه می‌کند.

مثلاً:

const country = "Türkiye";

function outer() {

    const city = "Istanbul";

    function inner() {

        const name = "Ali";

        console.log(name);
        console.log(city);
        console.log(country);

    }

    inner();
}

outer();

برای پیدا کردن country، جاوااسکریپت از Scope داخلی به سمت Scopeهای بیرونی حرکت می‌کند.

می‌توان این ساختار را به شکل زیر تصور کرد:

Global Scope
    ↓
outer Scope
    ↓
inner Scope

Execution Context چیست؟

هر بار که جاوااسکریپت کدی را اجرا می‌کند، محیطی برای اجرای آن ایجاد می‌شود که به آن Execution Context گفته می‌شود.

برای شروع می‌توانیم سه مفهوم مهم را در نظر بگیریم:

Global Execution Context
Function Execution Context
Eval Execution Context

در برنامه‌های معمول جاوااسکریپت، بیشتر با Global و Function Execution Context سر و کار داریم.

Global Execution Context

هنگام اجرای فایل جاوااسکریپت، ابتدا یک Global Execution Context ایجاد می‌شود.

مثلاً:

const name = "Ali";

console.log(name);

اجرای برنامه از Context مربوط به سطح Global شروع می‌شود.

Function Execution Context

هر بار که یک Function اجرا می‌شود، Execution Context مربوط به آن Function ایجاد می‌شود.

مثلاً:

function greet() {

    const message = "Hello";

    console.log(message);

}

greet();

وقتی greet() اجرا می‌شود، محیط اجرای مربوط به آن ایجاد می‌شود.

Call Stack چیست؟

جاوااسکریپت برای مدیریت اجرای Functionها از ساختاری به نام Call Stack استفاده می‌کند.

Stack یعنی ساختاری که معمولاً با قانون:

Last In, First Out

کار می‌کند.

یعنی آخرین چیزی که وارد Stack شود، زودتر خارج می‌شود.

مثال Call Stack

function first() {

    second();

}

function second() {

    third();

}

function third() {

    console.log("Hello");

}

first();

می‌توان اجرای آن را به صورت ساده این‌گونه تصور کرد:

third()
second()
first()
Global

ابتدا first() وارد Stack می‌شود.

سپس second().

سپس third().

وقتی third() تمام شود، از Stack خارج می‌شود.

سپس second() و بعد first().

Stack Overflow

اگر یک Function بدون توقف خودش را صدا بزند:

function test() {

    test();

}

test();

Function به صورت بی‌نهایت فراخوانی می‌شود.

در نهایت Call Stack پر شده و خطایی مانند:

Maximum call stack size exceeded

دریافت می‌کنیم.

این یکی از دلایل اهمیت کنترل Recursive Functionها است.

Hoisting چیست؟

Hoisting رفتاری از جاوااسکریپت است که در آن برخی Declarationها پیش از اجرای کد، در فرآیند آماده‌سازی Execution Context مورد پردازش قرار می‌گیرند.

یکی از ساده‌ترین مثال‌ها:

console.log(name);

var name = "Ali";

نتیجه:

undefined

می‌توان رفتار آن را به شکل مفهومی این‌گونه در نظر گرفت:

var name;

console.log(name);

name = "Ali";

البته این فقط یک مدل ساده برای درک رفتار است و به این معنی نیست که موتور جاوااسکریپت واقعاً کد را دقیقاً به این شکل جابه‌جا می‌کند.

Hoisting و Function Declaration

Function Declaration نیز رفتار Hoisting دارد.

مثلاً:

sayHello();

function sayHello() {

    console.log("Hello");

}

این کد اجرا می‌شود.

چون Function Declaration پیش از اجرای بخش مربوط به Call قابل شناسایی است.

Hoisting و let

حالا:

console.log(name);

let name = "Ali";

با خطا مواجه می‌شویم.

دلیل آن مفهوم مهمی به نام Temporal Dead Zone است.

Temporal Dead Zone

برای let و const، از ابتدای Scope تا محل Declaration، متغیر در وضعیتی قرار دارد که نمی‌توان قبل از Declaration به آن دسترسی داشت.

این محدوده را Temporal Dead Zone یا TDZ می‌نامیم.

مثلاً:

console.log(age);

let age = 25;

باعث خطا می‌شود.

const و TDZ

همین رفتار برای const نیز وجود دارد:

console.log(country);

const country = "Türkiye";

این کد نیز خطا ایجاد می‌کند.

Closure چیست؟

Closure یکی از مهم‌ترین مفاهیم جاوااسکریپت است.

Closure زمانی ایجاد می‌شود که یک Function بتواند به متغیرهای Scope بیرونی خود دسترسی داشته باشد، حتی زمانی که Function بیرونی اجرای خود را تمام کرده است.

این تعریف در ابتدا ممکن است کمی پیچیده باشد.

با مثال بهتر می‌توان آن را فهمید.

مثال ساده Closure

function outer() {

    const message = "Hello";

    function inner() {

        console.log(message);

    }

    return inner;
}

حالا:

const result = outer();

result();

نتیجه:

Hello

نکته مهم این است که outer() تمام شده است، اما inner() هنوز به message دسترسی دارد.

این یکی از ویژگی‌های مهم Closure است.

مثال کاربردی Closure

می‌توانیم یک Counter ایجاد کنیم:

function createCounter() {

    let count = 0;

    return function () {

        count++;

        return count;

    };
}

حالا:

const counter = createCounter();

هر بار:

console.log(counter());
console.log(counter());
console.log(counter());

نتیجه:

1
2
3

متغیر count مستقیماً از بیرون قابل دسترسی نیست، اما Function داخلی می‌تواند آن را حفظ و تغییر دهد.

چرا Closure کاربردی است؟

Closure در موارد مختلفی استفاده می‌شود، مانند:

  • نگهداری State خصوصی

  • ساخت Functionهای قابل تنظیم

  • Callbackها

  • Event Handlerها

  • Moduleها

  • مدیریت State

  • برخی الگوهای طراحی

متغیر خصوصی با Closure

مثلاً:

function createAccount() {

    let balance = 0;

    return {

        deposit(amount) {
            balance += amount;
        },

        getBalance() {
            return balance;
        }

    };
}

استفاده:

const account =
    createAccount();

account.deposit(1000);

console.log(
    account.getBalance()
);

نتیجه:

1000

اما:

console.log(account.balance);

نتیجه:

undefined

زیرا balance مستقیماً Property آن Object نیست.

this چیست؟

this یکی از موضوعات مهم جاوااسکریپت است.

مقدار this به نحوه فراخوانی Function بستگی دارد و در حالت‌های مختلف می‌تواند مقدار متفاوتی داشته باشد.

مثلاً در یک Method:

const user = {

    name: "Ali",

    sayHello() {

        console.log(this.name);

    }

};

user.sayHello();

در این حالت this به Object مربوط به user اشاره می‌کند.

this در Method

مثال:

const person = {

    name: "Reza",

    introduce() {

        console.log(
            `My name is ${this.name}`
        );

    }

};

person.introduce();

نتیجه:

My name is Reza

تغییر مقدار Property با this

const user = {

    name: "Ali",
    age: 25,

    birthday() {

        this.age++;

    }

};

user.birthday();

console.log(user.age);

نتیجه:

26

this در Function معمولی

نباید تصور کنیم this همیشه به Object اشاره می‌کند.

در Function معمولی:

function showThis() {

    console.log(this);

}

مقدار this به نحوه اجرا و محیط کد بستگی دارد.

در جاوااسکریپت مدرن، مخصوصاً در Strict Mode، رفتار this در Functionهای معمولی با مثال Method تفاوت دارد.

برای همین بهتر است this را بر اساس نحوه فراخوانی Function بررسی کنیم.

this در Arrow Function

Arrow Function رفتار متفاوتی با this دارد.

Arrow Function خودش this جدید ایجاد نمی‌کند و this را از Scope بیرونی دریافت می‌کند.

مثال:

const user = {

    name: "Ali",

    showName: function () {

        const show = () => {

            console.log(this.name);

        };

        show();

    }

};

user.showName();

نتیجه:

Ali

در اینجا Arrow Function مقدار this را از Function بیرونی دریافت کرده است.

یک اشتباه رایج درباره Arrow Function

بعضی افراد تصور می‌کنند:

const user = {

    name: "Ali",

    sayHello: () => {

        console.log(this.name);

    }

};

حتماً this به user اشاره می‌کند.

این تصور درست نیست.

Arrow Function this مخصوص خودش را ایجاد نمی‌کند.

به همین دلیل برای Methodهایی که به this مربوط به Object نیاز دارند، معمولاً Function Method معمولی انتخاب مناسب‌تری است.

Prototype چیست؟

هر Object در جاوااسکریپت دارای ارتباطی با یک Object دیگر است که به آن Prototype گفته می‌شود.

Prototype یکی از پایه‌های مهم مدل شیءگرایی جاوااسکریپت است.

برای مثال:

const user = {
    name: "Ali"
};

این Object به یک Prototype متصل است که از آن برخی امکانات را به ارث می‌برد.

به همین دلیل می‌توانیم بنویسیم:

user.toString();

در حالی که خودمان toString را داخل Object تعریف نکرده‌ایم.

Prototype Chain

اگر جاوااسکریپت یک Property یا Method را در Object پیدا نکند، می‌تواند در Prototype آن جستجو کند.

این روند می‌تواند ادامه پیدا کند.

به این زنجیره:

Object
   ↓
Prototype
   ↓
Another Prototype
   ↓
null

Prototype Chain گفته می‌شود.

مشاهده Prototype

برای مشاهده Prototype یک Object می‌توان از:

Object.getPrototypeOf(user);

استفاده کرد.

Constructor Function

قبل از معرفی Classها در جاوااسکریپت، برای ساخت Objectهای مشابه از Constructor Functionها استفاده می‌شد.

مثلاً:

function User(name, age) {

    this.name = name;
    this.age = age;

}

سپس:

const user1 =
    new User("Ali", 25);

const user2 =
    new User("Reza", 30);

عملگر new

وقتی می‌نویسیم:

new User("Ali", 25);

جاوااسکریپت فرآیندهایی را برای ایجاد Object جدید انجام می‌دهد.

به صورت ساده می‌توان گفت:

  1. یک Object جدید ایجاد می‌شود.

  2. Prototype مناسب به آن متصل می‌شود.

  3. this در Constructor به Object جدید مربوط می‌شود.

  4. Constructor اجرا می‌شود.

  5. Object جدید برگردانده می‌شود.

این توضیح ساده‌شده است، اما برای درک اولیه new مناسب است.

افزودن Method به Prototype

اگر Method را داخل Constructor ایجاد کنیم:

function User(name) {

    this.name = name;

    this.sayHello = function () {

        console.log(
            `Hello ${this.name}`
        );

    };

}

برای هر Instance یک Function جدید ساخته می‌شود.

می‌توانیم Method را روی Prototype قرار دهیم:

User.prototype.sayHello =
    function () {

        console.log(
            `Hello ${this.name}`
        );

    };

اکنون Instanceها می‌توانند Method را از Prototype دریافت کنند.

Class و Prototype

وقتی در جاوااسکریپت از:

class User {

    constructor(name) {
        this.name = name;
    }

    sayHello() {
        console.log(
            `Hello ${this.name}`
        );
    }

}

استفاده می‌کنیم، در پشت مدل شیءگرایی جاوااسکریپت همچنان مفهوم Prototype وجود دارد.

Class در جاوااسکریپت Syntax راحت‌تری برای کار با این مدل ارائه می‌کند.

Reference چیست؟

یکی از نکات مهم جاوااسکریپت این است که Objectها و Arrayها با Reference رفتار می‌کنند.

مثلاً:

const user1 = {
    name: "Ali"
};

const user2 = user1;

user2.name = "Reza";

console.log(user1.name);

نتیجه:

Reza

چرا؟

چون user1 و user2 به همان Object اشاره می‌کنند.

مقایسه با Primitive

برای مقدارهای Primitive مانند Number:

let a = 10;

let b = a;

b = 20;

console.log(a);
console.log(b);

نتیجه:

10
20

در اینجا تغییر b مقدار a را تغییر نمی‌دهد.

Shallow Copy

برای ایجاد یک Object جدید می‌توانیم از Spread استفاده کنیم:

const user1 = {
    name: "Ali",
    age: 25
};

const user2 = {
    ...user1
};

user2.name = "Reza";

console.log(user1.name);
console.log(user2.name);

نتیجه:

Ali
Reza

محدودیت Shallow Copy

Spread فقط یک Shallow Copy ایجاد می‌کند.

مثلاً:

const user1 = {

    name: "Ali",

    address: {
        city: "Istanbul"
    }

};

const user2 = {
    ...user1
};

user2.address.city =
    "Ankara";

ممکن است:

console.log(
    user1.address.city
);

نیز مقدار جدید را نشان دهد.

چون Object داخلی همچنان Reference مشترک دارد.

Deep Copy

برای برخی داده‌های ساده می‌توان از:

structuredClone()

استفاده کرد.

مثلاً:

const user1 = {

    name: "Ali",

    address: {
        city: "Istanbul"
    }

};

const user2 =
    structuredClone(user1);

user2.address.city =
    "Ankara";

console.log(
    user1.address.city
);

console.log(
    user2.address.city
);

در این حالت Object داخلی نیز مستقل کپی می‌شود.

البته روش مناسب کپی کردن داده‌ها به نوع داده و نیاز پروژه بستگی دارد.

Immutability چیست؟

Immutability به معنای این است که به جای تغییر مستقیم داده، نسخه جدیدی از آن ایجاد کنیم.

مثلاً:

const user = {
    name: "Ali",
    age: 25
};

به جای تغییر مستقیم:

user.age = 26;

می‌توانیم Object جدید ایجاد کنیم:

const updatedUser = {
    ...user,
    age: 26
};

این تکنیک در بسیاری از معماری‌ها و کتابخانه‌های مدرن جاوااسکریپت اهمیت زیادی دارد.

Garbage Collection چیست؟

جاوااسکریپت دارای مکانیزمی برای مدیریت حافظه است که به آن Garbage Collection گفته می‌شود.

به صورت ساده، وقتی دیگر هیچ Reference قابل دسترسی به یک Object وجود نداشته باشد، موتور جاوااسکریپت می‌تواند حافظه مربوط به آن را در زمان مناسب آزاد کند.

مثلاً:

let user = {
    name: "Ali"
};

user = null;

اگر Reference دیگری به Object وجود نداشته باشد، آن Object دیگر از طریق user قابل دسترسی نیست و می‌تواند توسط Garbage Collector جمع‌آوری شود.

Memory Leak چیست؟

گاهی برنامه به دلیل نگه داشتن Referenceهای غیرضروری، حافظه را بیشتر از نیاز مصرف می‌کند.

به این وضعیت می‌توان Memory Leak گفت.

یکی از نمونه‌های رایج در برنامه‌های Browser، Event Listenerهایی هستند که دیگر لازم نیستند اما همچنان به عناصر یا Objectها متصل باقی مانده‌اند.

برای همین مدیریت صحیح Eventها و منابع اهمیت دارد.

مثال ترکیبی

اکنون چند مفهوم را با هم ترکیب کنیم.

function createCounter(start = 0) {

    let count = start;

    return {

        increment() {
            count++;
        },

        decrement() {
            count--;
        },

        getValue() {
            return count;
        }

    };
}

استفاده:

const counter =
    createCounter(10);

counter.increment();
counter.increment();

console.log(
    counter.getValue()
);

نتیجه:

12

در این مثال از چند مفهوم استفاده شده است:

  • Function

  • Default Parameter

  • Closure

  • Object

  • Method

  • State خصوصی

یک مثال دیگر با Scope و Closure

function createGreeting(greeting) {

    return function (name) {

        return `${greeting}, ${name}!`;

    };
}

حالا:

const sayHello =
    createGreeting("Hello");

const sayWelcome =
    createGreeting("Welcome");

استفاده:

console.log(
    sayHello("Ali")
);

console.log(
    sayWelcome("Reza")
);

نتیجه:

Hello, Ali!
Welcome, Reza!

هر Function مقدار greeting مربوط به خودش را از طریق Closure حفظ کرده است.

نکات مهم درباره مفاهیم پیشرفته

همه چیز را یک‌باره حفظ نکنید

مفاهیمی مانند:

Closure
Prototype
Execution Context
Call Stack

با مطالعه یک‌باره کاملاً جا نمی‌افتند.

مهم این است که مثال‌های مختلف را اجرا و رفتار آن‌ها را مشاهده کنید.

رفتار this را از روی محل تعریف Function تعیین نکنید

به‌خصوص در Functionهای معمولی، باید به نحوه فراخوانی Function توجه کنید.

var را با let و const مقایسه کنید

در پروژه‌های جدید بهتر است تفاوت Scope و Hoisting آن‌ها را به خوبی بدانید.

Object و Array را Reference در نظر بگیرید

این موضوع در زمان Copy کردن اطلاعات بسیار مهم است.

اشتباهات رایج

اشتباه اول: تصور اینکه let و const اصلاً Hoist نمی‌شوند

رفتار آن‌ها با var متفاوت است، اما Declaration آن‌ها در فرآیند آماده‌سازی Scope در نظر گرفته می‌شود و دسترسی قبل از Declaration به دلیل TDZ امکان‌پذیر نیست.

اشتباه دوم: تصور اینکه this همیشه Object فعلی است

this به نحوه فراخوانی Function وابسته است و در Arrow Function نیز رفتار متفاوتی دارد.

اشتباه سوم: تصور اینکه Spread یک Deep Copy است

این کد:

const copy = {
    ...original
};

فقط یک Shallow Copy ایجاد می‌کند.

اشتباه چهارم: تصور اینکه Closure فقط یک مفهوم تئوری است

Closure در جاوااسکریپت واقعی کاربرد زیادی دارد و در Callbackها، Eventها، Moduleها و مدیریت State دیده می‌شود.

اشتباه پنجم: استفاده از Recursion بدون شرط پایان

اگر Function خودش را بدون شرط پایان صدا بزند، ممکن است Call Stack پر شود.

تمرین‌ها

تمرین ۱ — Scope

کدی بنویسید که یک متغیر Global و یک متغیر Local داشته باشد.

بررسی کنید کدام Functionها به هرکدام دسترسی دارند.

تمرین ۲ — Hoisting

خروجی کد زیر را پیش‌بینی کنید:

console.log(a);

var a = 10;

سپس همین مثال را با let اجرا کنید و تفاوت را بررسی کنید.

تمرین ۳ — Closure

تابعی به نام createCounter بنویسید که هر بار اجرای Function داخلی، عدد را یکی افزایش دهد.

تمرین ۴ — this

یک Object به نام person ایجاد کنید که دارای:

name
age
introduce()

باشد و داخل introduce() از this استفاده کنید.

تمرین ۵ — Prototype

یک Constructor Function به نام Product بسازید و Method آن را روی Prototype قرار دهید.

تمرین ۶ — Shallow Copy

یک Object تو در تو ایجاد کنید و با Spread آن را کپی کنید.

سپس تغییر Object داخلی را بررسی کنید.

تمرین ۷ — Deep Copy

همان مثال را با structuredClone() انجام دهید و نتیجه را با Shallow Copy مقایسه کنید.

چالش عملی

یک سیستم ساده برای ساخت حساب کاربری با Closure ایجاد کنید.

تابعی به نام:

createUser()

بسازید که اطلاعات زیر را مدیریت کند:

name
balance

اما balance نباید مستقیماً از بیرون قابل تغییر باشد.

تابع باید متدهای زیر را برگرداند:

deposit()
withdraw()
getBalance()
getName()

قوانین:

  1. balance باید خصوصی باشد.

  2. deposit() مبلغ را به موجودی اضافه کند.

  3. withdraw() فقط در صورت کافی بودن موجودی برداشت کند.

  4. getBalance() موجودی فعلی را برگرداند.

  5. getName() نام کاربر را برگرداند.

  6. برای مقدار اولیه Balance یک Default Parameter قرار دهید.

  7. از Closure برای نگهداری اطلاعات خصوصی استفاده کنید.

نمونه استفاده:

const user =
    createUser("Ali", 1000);

user.deposit(500);

user.withdraw(200);

console.log(
    user.getBalance()
);

نتیجه:

1300

و این نباید امکان‌پذیر باشد:

user.balance = 999999;

چون balance نباید Property عمومی باشد.

جمع‌بندی

در این مقاله وارد بخش مهمی از مفاهیم پیشرفته جاوااسکریپت شدیم.

با مفاهیم زیر آشنا شدیم:

  • Scope

  • Global Scope

  • Function Scope

  • Block Scope

  • Lexical Scope

  • Scope Chain

  • Execution Context

  • Global Execution Context

  • Function Execution Context

  • Call Stack

  • Stack Overflow

  • Hoisting

  • Temporal Dead Zone

  • Closure

  • this

  • تفاوت this در Function معمولی و Arrow Function

  • Prototype

  • Prototype Chain

  • Constructor Function

  • new

  • Reference

  • Shallow Copy

  • Deep Copy

  • Immutability

  • Garbage Collection

  • Memory Leak

مهم‌ترین نکته این است که این مفاهیم را فقط به صورت تئوری حفظ نکنید. کدهای مثال را خودتان اجرا کنید، مقدارها را تغییر دهید و نتیجه را مشاهده کنید.

اکنون درک بهتری از نحوه اجرای جاوااسکریپت و رفتار بخش‌های مختلف زبان دارید.

۰۰

نظرات

کد در دسترس نیست

هنوز نظری ثبت نشده است.