فصل هفتم
برنامه نویسی شی گرا
(OOP) Object Oriented Programming
مطمئناً درک برنامه نویسی شی گرا (OOP) برای درک اینکه چرا و چگونه جاوا اسکریپت ماهیت شی گرا خود را پیاده سازی می کند بسیار مهم است. بیایید به مفهوم OOP و کاربرد آن در جاوا اسکریپت بپردازیم.
برنامه نویسی شی گرا چیست؟
برنامه نویسی شی گرا (OOP) یک الگوی برنامه نویسی است که از “اشیاء” برای طراحی برنامه های کاربردی و برنامه های کامپیوتری استفاده می کند. از چندین اصل مانند کپسولهسازی، وراثت و چند شکلی برای افزایش خوانایی کد، قابلیت استفاده مجدد و مقیاسپذیری استفاده میکند. در اینجا خلاصه ای از این اصول آورده شده است:
- کپسولهسازی / Encapsulation: این اصل دادهها (ویژگیها) و روشها (توابع) را که روی دادهها کار میکنند در واحدهای واحدی به نام «اشیاء» دستهبندی میکند. دسترسی مستقیم به برخی از اجزای یک شی را محدود می کند، که می تواند از تغییر تصادفی داده ها جلوگیری کند.
- وراثت / Inheritance: این به یک کلاس اجازه می دهد تا ویژگی ها و متدهای کلاس دیگر را به ارث ببرد. ما از آن برای ایجاد یک کلاس جدید استفاده می کنیم که نسخه اصلاح شده یک کلاس موجود است.
- چند شکلی / Polymorphy: این اصل اجازه می دهد تا اشیاء از کلاس های مختلف به عنوان اشیاء یک ابر کلاس مشترک در نظر گرفته شوند. این یک رابط واحد را قادر می سازد تا فرم های مختلف زیرین (انواع داده) را نشان دهد.
- Abstraction: این اصل جزئیات پیاده سازی پیچیده را پنهان می کند و فقط ویژگی های ضروری یک شی را نشان می دهد. این به کاهش پیچیدگی و تلاش برنامه نویسی کمک می کند.
چرا جاوا اسکریپت یک زبان شی گرا در نظر گرفته می شود؟
جاوا اسکریپت یک زبان برنامه نویسی شی گرا در نظر گرفته می شود زیرا از اصول OOP از طریق نمونه های اولیه و سیستم کلاس خود (معرفی شده در ECMAScript 2015/ES6) پشتیبانی می کند. علیرغم اینکه جاوا اسکریپت مبتنی بر نمونه اولیه است، می توان از روشی شی گرا استفاده کرد. در اینجا نحوه هماهنگی جاوا اسکریپت با اصول OOP آمده است:
- اشیاء و نمونه های اولیه: جاوا اسکریپت اساساً در مورد اشیا است. یک شی در جاوا اسکریپت یک موجودیت مستقل با خصوصیات و نوع است. این زبان به جای وراثت کلاسیک از نمونههای اولیه استفاده میکند، اما با تنظیم نمونه اولیه (یعنی شی والد) یک شی به شی دیگر، برنامهنویسی شیگرا را امکانپذیر میکند.
- کلاس ها (ES6): جاوا اسکریپت دستور کلاسی را برای ایجاد اشیا و مدیریت وراثت معرفی کرد. زیر سرپوش، کلاس ها در جاوا اسکریپت فقط توابع ویژه هستند. سینتکس کلاس یک مدل ارثی شی گرا جدید به جاوا اسکریپت معرفی نمی کند. این فقط قند نحوی بر وراثت مبتنی بر نمونه اولیه موجود است و استفاده از آن را آسانتر میکند.
- Encapsulation: جاوا اسکریپت با ایجاد توابع و متغیرهایی که از خارج از تابع کپسولهسازی قابل دسترسی نیستند، از کپسولهسازی پشتیبانی میکند. افزودههای اخیر «let» و «const» برای محدوده بلوک و استفاده از بستهها، این قابلیت را افزایش میدهد.
- وراثت: از طریق زنجیرهسازی نمونه اولیه، اشیاء جاوا اسکریپت ویژگیهایی را از اشیاء دیگر به ارث میبرند و به طور موثر به یک نوع شی اجازه میدهد تا متدها و ویژگیها را از دیگری به ارث ببرد.
- چند شکلی: جاوا اسکریپت از چندشکلی پشتیبانی می کند. به عنوان مثال، یک تابع را می توان بر روی اشیاء مختلف به ارث رسیده از یک والد یا رابط استفاده کرد.
درک اصول OOP زمینه ای را به این موضوع می دهد که چرا جاوا اسکریپت بر اشیاء تأکید دارد. در جاوا اسکریپت، تقریباً همه چیز یک شی است، از انواع داده های اولیه (زمانی که مانند اشیاء استفاده می شوند) تا ساختارهای داده پیچیده تر. جاوا اسکریپت از اشیاء برای ساخت برنامه های کاربردی انعطاف پذیرتر و مقیاس پذیرتر استفاده می کند و با الگوی OOP برای ساختار برنامه ها همسو می شود.
اشیاء داده ها و عملکرد را در اجزای ماژولار و قابل استفاده مجدد با هم کپسوله می کنند. ماهیت پویای جاوا اسکریپت امکان طراحی های شی گرا انعطاف پذیر و قدرتمند را فراهم می کند و آن را به زبانی قدرتمند برای طیف گسترده ای از برنامه ها تبدیل می کند.
اشیاء جاوا اسکریپت – Object in JS
جاوا اسکریپت به عنوان یک زبان چند پارادایم می ایستد و دارای ویژگی های فراوانی است که به آن تطبیق پذیری برای مقابله با طیف گسترده ای از وظایف می دهد. محور قابلیت های آن مفهوم اشیا است. این عنصر اساسی نه تنها ساختارهای خود زبان، مانند آرایهها و توابع را زیربنا میدهد، بلکه به گستره وسیعی از APIهای مرورگر که بر روی جاوا اسکریپت ساخته شدهاند نیز قدرت میدهد.
علاوه بر این، این زبان به شما این امکان را می دهد که اشیاء سفارشی خود را بسازید، در نتیجه یک راه ساده برای بسته بندی توابع و متغیرهای مرتبط در واحدهای منسجم فراهم می کند. این اشیاء دارای اهداف دوگانه هستند، هم به عنوان محفظه های کارآمد برای داده ها و هم به عنوان مکانیسم هایی برای محصور کردن عملکردها عمل می کنند. با کاوش عمیق تر در جاوا اسکریپت، درک ماهیت شی گرا زبان ضروری می شود.
این فصل به ابهام زدایی از اشیاء در جاوا اسکریپت اختصاص یافته است و کاوش کاملی در مورد تئوری پشت اشیاء و نحو مورد استفاده برای دستکاری آنها ارائه می دهد. از طریق این سفر، هدف ما این است که شما را با دانش برای ایجاد و استفاده مؤثر از اشیاء خود مسلح کنیم.
درک ماهیت اشیاء جاوا اسکریپت
اشیاء در جاوا اسکریپت شبیه صندوقچه های گنج هستند که ملغمه ای از داده ها و عملکردها را ذخیره می کنند. این مجموعه ها شامل عناصر مختلفی هستند که هر کدام با یک نام منحصر به فرد برچسب گذاری شده اند و ارزش یا عملکرد خود را دارند. این تجمیع ستون فقرات آنچه را که ما به عنوان اشیا می شناسیم تشکیل می دهد – ساختاری که در سازماندهی و مدیریت داده ها در جاوا اسکریپت نقش اساسی دارد.
پیش نیازها:
- درک اساسی از HTML و CSS.
- آشنایی با مفاهیم اصلی جاوا اسکریپت، همانطور که در مراحل اولیه و بلوک های سازنده زبان مطرح شد.
آناتومی اشیاء جاوا اسکریپت
سناریویی را در نظر بگیرید که در آن یک کتابخانه دیجیتال برای فهرستنویسی کتابها ایجاد میکنیم. هر کتاب در این کتابخانه را می توان به عنوان یک شی نشان داد، جزئیاتی مانند عنوان، نویسنده و روشی برای نمایش مختصر این اطلاعات را در بر می گیرد.
خلق اولین شی ما: یک کتاب
const book = {
title: “JavaScript: The Good Parts”,
author: “Douglas Crockford”,
displayInfo: function() {
console.log(`${this.title} by ${this.author}`);
}
};
بینش های کلیدی:
اشیاء در داخل پرانتزهای مجعد {} تعریف میشوند و هر عضو (یا ویژگی) از یک الگوی کلیدی پیروی میکند: مقدار.
توابع درون اشیا، که به عنوان متدها شناخته می شوند، شی را قادر می سازند تا با داده های خود تعامل داشته باشد.
این کلمه کلیدی دسترسی به اعضای خود شی را فراهم می کند.
دسترسی به ویژگی های شی: نماد نقطه و براکت
برای بازیابی یا اصلاح ویژگی های شی کتاب خود، از دو نماد اصلی استفاده می کنیم:
- Dot Notation: book.title یک رویکرد ساده برای دسترسی به ویژگی ها ارائه می دهد.
- علامت گذاری براکت: کتاب [“نویسنده”] زمانی مفید است که نام ویژگی ها پویا یا در متغیرها ذخیره شود.
سازندگان: طرحبندی اشیاء
وقتی کتابخانه دیجیتال ما گسترش مییابد، ایجاد دستی یک شی برای هر کتاب غیرعملی میشود. اینجاست که سازندگان وارد عمل میشوند و بهعنوان نقشهای برای ایجاد چندین شی از یک نوع عمل میکنند.
function Book(title, author) {
this.title = title;
this.author = author;
this.displayInfo = function() {
console.log(`${this.title} by ${this.author}`);
};
}
const myBook = new Book(“Eloquent JavaScript”, “Marijn Haverbeke”);
myBook.displayInfo();
سناریوی عملی: ایجاد رابط کتابخانه دیجیتال
برای تحکیم درک خود، بیایید شروع به ایجاد یک رابط کاربری ساده برای کتابخانه دیجیتال خود کنیم. این رابط به کاربران امکان می دهد کتاب هایی را به مجموعه اضافه کرده و آنها را مشاهده کنند.
ساختار HTML
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>Digital Library</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<div id=”libraryForm”>
<input type=”text” id=”title” placeholder=”Book Title”>
<input type=”text” id=”author” placeholder=”Author”>
<button onclick=”addBookToLibrary()”>Add Book</button>
</div>
<div id=”libraryDisplay”></div>
<script src=”script.js”></script>
</body>
</html>
CSS Style
#libraryForm {
margin-bottom: 20px;
}
#libraryDisplay {
margin-top: 20px;
}
JavaScript: حیات بخشیدن به کتابخانه
// Define an array to hold all book objects for our digital library.
let library = [];
// Define a constructor function for creating ‘Book’ objects.
// Each book will have a title and an author.
function Book(title, author) {
// Assign the ‘title’ and ‘author’ parameters to the object’s properties.
this.title = title;
this.author = author;
}
// This function adds a new book to the library.
// It is triggered by clicking the ‘Add Book’ button in the HTML.
function addBookToLibrary() {
// Retrieve the book title and author from the input fields.
const title = document.getElementById(‘title’).value;
const author = document.getElementById(‘author’).value;
// Create a new ‘Book’ object with the input values.
const newBook = new Book(title, author);
// Add the newly created book object to the ‘library’ array.
library.push(newBook);
// Refresh the library display to include the new book.
displayLibrary();
}
// This function updates the library display.
// It shows all books currently stored in the ‘library’ array.
function displayLibrary() {
// Access the ‘libraryDisplay’ div where books will be shown.
const display = document.getElementById(‘libraryDisplay’);
// Clear the display to ensure we’re not duplicating books.
display.innerHTML = ”;
// Loop through each book in the ‘library’ array.
library.forEach(book => {
// For each book, create a new ‘div’ element.
const bookElement = document.createElement(‘div’);
// Set the text content of the ‘div’ to show the book’s title and author.
bookElement.textContent = `${book.title} by ${book.author}`;
// Add the newly created ‘div’ to the ‘libraryDisplay’ div, making the book visible.
display.appendChild(bookElement);
});
}
- سازنده Book، طرح اولیه را برای هر شیء کتاب تعریف می کند.
- تابع addBookToLibrary ورودی فرم را می گیرد، یک شی کتاب جدید ایجاد می کند و آن را به آرایه کتابخانه اضافه می کند.
- تابع displayLibrary روی آرایه کتابخانه تکرار میشود و عناصری را برای هر کتاب ایجاد و نمایش می دهد.
این مثال عملی نشان میدهد که چگونه اشیا میتوانند مدیریت دادهها و عملکردهای مرتبط را سادهسازی کنند و یک رویکرد ساختاریافته برای چالشهای برنامهنویسی ارائه دهند.
نتیجه:
نمونه های اولیه / Prototype
درک مفهوم نمونه های اولیه / Prototype برای تسلط بر جاوا اسکریپت ضروری است، زیرا در قلب مکانیسم وراثت شی جاوا اسکریپت قرار دارد. در اینجا، نمونههای اولیه، نقش زنجیرههای نمونه اولیه و روشهای تنظیم نمونه اولیه یک شی را بررسی میکنیم.
مقدمه ای بر نمونه های اولیه اشیاء
در جاوا اسکریپت، نمونه های اولیه نقش محوری در ارث بردن خواص و متدها از یک شی به شی دیگر دارند. این پایه و اساس وراثت مبتنی بر نمونه اولیه جاوا اسکریپت است و آن را از وراثت کلاسیک موجود در زبان هایی مانند جاوا یا C++ متمایز می کند.
ملزومات زنجیره های اولیه
تصور کنید یک شی ساده در جاوا اسکریپت به صورت زیر ایجاد کنید:
// Creating a basic object with a property and a method
const myObject = {
city: “Madrid”,
greet() {
console.log(`Greetings from ${this.city}`);
},
};
هنگام فراخوانی myObject.greet();، پیامی دریافت می کنید: “Greetings from Madrid”. پس از بررسی myObject در کنسول، نه تنها City و Greet بلکه تعداد زیادی از ویژگی های دیگر مانند toString، valueOf، و به ویژه، __proto__ را متوجه خواهید شد.
این ویژگیهای اضافی بخشی از نمونه اولیه myObject هستند – یک شی داخلی که myObject متدها و ویژگیها را از آن به ارث میبرد. این وراثت بخشی از چیزی است که به عنوان زنجیره اولیه شناخته می شود.
// Accessing an inherited method
myObject.toString(); // Outputs: “[object Object]”
درک وراثت نمونه اولیه
هر شی جاوا اسکریپت یک نمونه اولیه دارد. نمونه اولیه خود یک شی است و می تواند نمونه اولیه خود را داشته باشد و یک “زنجیره نمونه اولیه” ایجاد کند. این زنجیره تا رسیدن به یک نمونه اولیه با نول به عنوان نمونه اولیه خود ادامه می یابد و پایان زنجیره را مشخص می کند.
برای مثال برای دیدن این زنجیره:
// Exploring the prototype chain
console.log(Object.getPrototypeOf(myObject)); // Object.prototype
این نشان می دهد که نمونه اولیه myObject Object.prototype است، نمونه اولیه که همه اشیا به طور پیش فرض از آن ارث می برند.
ویژگی های سایه زدن – Shadowing Properties
چه می شود اگر یک شی و نمونه اولیه آن دارای ویژگی هایی با نام یکسان باشند؟ ویژگی خود شی، ویژگی نمونه اولیه را تحت الشعاع قرار می دهد. این به عنوان سایه مالکیت شناخته می شود.
تنظیم نمونه اولیه یک شی
برای تنظیم صریح نمونه اولیه یک شی، جاوا اسکریپت مکانیسم هایی مانند Object.create() و توابع سازنده را ارائه می دهد.
// Creating an object with a specific prototype
const personPrototype = {
greet() {
console.log(“hello!”);
},
};
const carl = Object.create(personPrototype);
carl.greet(); // Outputs: “hello!”
در اینجا Object.create() یک شی جدید به نام carl ایجاد می کند که نمونه اولیه آن personPrototype است.
استفاده از سازندگان -Utilizing Constructors
توابع سازنده به شما این امکان را می دهند که نمونه اولیه را برای تمام نمونه های ایجاد شده از سازنده تعریف کنید.
// Defining a constructor function
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hi, my name is ${this.name}`);
};
const alice = new Person(“Alice”);
alice.greet(); // Outputs: “Hi, my name is Alice”
در این مثال، تمام نمونههای Person از Person.prototype ارث میبرند و روشهای مشترک مانند greet را فعال میکنند.
نمونه های اولیه: ستون فقرات اشیاء جاوا اسکریپت
از طریق زنجیرههای نمونه اولیه، جاوا اسکریپت به ارث میرسد و به اشیا اجازه میدهد تا عملکردها را به طور موثر به اشتراک بگذارند و گسترش دهند. این سیستم زیربنای ویژگی های شی گرا زبان است و توسعه دهندگان را قادر می سازد تا ساختارهای کد پیچیده و مدولار را بسازند.
درک نمونههای اولیه و زنجیرههای آنها گامی به سوی تسلط بر رویکرد پویا و انعطافپذیر جاوا اسکریپت به اشیا و وراثت است و زمینه را برای کاوش در مفاهیم برنامهنویسی شی گرا عمیقتر در زبان فراهم میکند.
بیایید یک مثال عملی را بررسی کنیم که وراثت نمونه اولیه جاوا اسکریپت را با یک برنامه وب کوچک نشان می دهد – یک رابط کاربری ساده که به کاربران اجازه می دهد با اشیایی که اشکال هندسی را نشان می دهند تعامل داشته باشند. این مثال شامل ایجاد یک سازنده شکل اولیه و گسترش آن برای ایجاد انواع خاصی از اشکال است.
سناریو: انتخابگر شکل
برنامه وب ما به کاربران این امکان را می دهد که یک شکل را از منوی کشویی انتخاب کنند و سپس با استفاده از نمونه های اولیه شی جاوا اسکریپت، ویژگی های خاص شکل انتخاب شده، مانند مساحت و محیط را نمایش دهند.
ساختار HTML
ابتدا HTML را با یک کشویی برای انتخاب شکل و بخشی برای نمایش خصوصیات شکل تنظیم می کنیم.
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Shape Selector</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<select id=”shapeSelect”>
<option value=”circle”>Circle</option>
<option value=”square”>Square</option>
</select>
<div id=”shapeInfo”></div>
<script src=”script.js”></script>
</body>
</html>
استایل CSS
در مرحله بعد، ما برخی از استایل های اولیه را اضافه می کنیم تا رابط کاربری خود را از نظر بصری جذاب تر کنیم.
/* style.css */
body {
font-family: Arial, sans-serif;
margin: 20px;
}
#shapeInfo {
margin-top: 20px;
}
منطق جاوا اسکریپت
اکنون، سازندههای شکل و روشهای نمونه اولیه را تعریف میکنیم، سپس شنونده رویداد را برای انتخاب شکل سیمکشی میکنیم.
// script.js
// Shape constructor
function Shape(name) {
this.name = name;
}
// Adding a method to the Shape prototype
Shape.prototype.displayInfo = function() {
return `Shape: ${this.name}<br>`;
};
// Circle constructor
function Circle(radius) {
Shape.call(this, ‘Circle’);
this.radius = radius;
}
// Setting Circle’s prototype and constructor reference
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
// Adding methods to Circle prototype
Circle.prototype.area = function() {
return Math.PI * this.radius * this.radius;
};
Circle.prototype.perimeter = function() {
return 2 * Math.PI * this.radius;
};
// Square constructor
function Square(sideLength) {
Shape.call(this, ‘Square’);
this.sideLength = sideLength;
}
// Setting Square’s prototype and constructor reference
Square.prototype = Object.create(Shape.prototype);
Square.prototype.constructor = Square;
// Adding methods to Square prototype
Square.prototype.area = function() {
return this.sideLength * this.sideLength;
};
Square.prototype.perimeter = function() {
return this.sideLength * 4;
};
// Event listener for shape selection
document.getElementById(‘shapeSelect’).addEventListener(‘change’, function() {
const shapeInfoDiv = document.getElementById(‘shapeInfo’);
let shape;
switch(this.value) {
case ‘circle’:
shape = new Circle(5); // Example radius
break;
case ‘square’:
shape = new Square(4); // Example side length
break;
}
shapeInfoDiv.innerHTML = shape.displayInfo() + `Area: ${shape.area().toFixed(2)}<br>Perimeter: ${shape.perimeter().toFixed(2)}`;
});
این کد جاوا اسکریپت نحوه استفاده از وراثت نمونه اولیه را برای گسترش یک سازنده شکل پایه با انواع شکل های خاص مانند دایره و مربع نشان می دهد. از روش Object.create برای تنظیم نمونه اولیه سازنده های مشتق شده استفاده می کند و اطمینان حاصل می کند که ویژگی سازنده به تابع سازنده صحیح برمی گردد.
پس از انتخاب یک شکل، شیء شکل مربوطه را نمونه سازی می کند و مساحت و محیط آن را در #shapeInfo div نمایش می دهد. این مثال قدرت و انعطافپذیری سیستم نمونه اولیه جاوا اسکریپت را در یک سناریوی عملی نشان میدهد و استفاده مجدد و گسترش کد را تسهیل میکند.
گسترش مثال انتخاب شکل
بیایید مثال انتخاب شکل را گسترش دهیم تا مفید بودن کلاسها (یا در مثال قبلی، توابع سازنده که مشابه کلاسها عمل میکنند) را برای ایجاد نمونههای جدید و گسترش برنامهمان بیشتر نشان دهیم.
سناریوی اضافی: ایجاد شکل پویا
فرض کنید میخواهیم برنامهمان را ارتقا دهیم تا به کاربران اجازه دهیم ابعاد یک دایره یا مربع را وارد کنند و به صورت پویا آن شکل را ایجاد کنند و ویژگیهای آن را نمایش دهند.
گسترش HTML
فیلدهای ورودی را به HTML خود اضافه می کنیم تا به کاربران اجازه دهیم ابعاد شکل انتخابی خود را وارد کنند.
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Dynamic Shape Creator</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<label for=”shapeSelect”>Select a shape:</label>
<select id=”shapeSelect”>
<option value=””>Please select</option>
<option value=”circle”>Circle</option>
<option value=”square”>Square</option>
</select>
<div id=”dimensionInput”></div>
<button id=”createShape”>Create Shape</button>
<div id=”shapeInfo”></div>
<script src=”script.js”></script>
</body>
</html>
اصلاح جاوا اسکریپت
ما جاوا اسکریپت خود را تغییر می دهیم تا ورودی ابعاد را مدیریت کند و به صورت پویا اشکالی با اندازه های تعریف شده توسط کاربر ایجاد کنیم.
// script.js
// Shape constructor
function Shape(name) {
this.name = name;
}
// Adding a method to the Shape prototype
Shape.prototype.displayInfo = function() {
return `Shape: ${this.name}<br>`;
};
// Circle constructor
function Circle(radius) {
Shape.call(this, ‘Circle’);
this.radius = radius;
}
// Setting Circle’s prototype and constructor reference
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
// Adding methods to Circle prototype
Circle.prototype.area = function() {
return Math.PI * this.radius * this.radius;
};
Circle.prototype.perimeter = function() {
return 2 * Math.PI * this.radius;
};
// Square constructor
function Square(sideLength) {
Shape.call(this, ‘Square’);
this.sideLength = sideLength;
}
// Setting Square’s prototype and constructor reference
Square.prototype = Object.create(Shape.prototype);
Square.prototype.constructor = Square;
// Adding methods to Square prototype
Square.prototype.area = function() {
return this.sideLength * this.sideLength;
};
Square.prototype.perimeter = function() {
return this.sideLength * 4;
};
// Expanding the event listener to handle dimension input
document.getElementById(‘shapeSelect’).addEventListener(‘change’, function() {
const dimensionInputDiv = document.getElementById(‘dimensionInput’);
let inputHTML = ”;
switch(this.value) {
case ‘circle’:
inputHTML = ‘Radius: <input type=”number” id=”radiusInput” min=”0″><br>’;
break;
case ‘square’:
inputHTML = ‘Side Length: <input type=”number” id=”sideLengthInput” min=”0″><br>’;
break;
}
dimensionInputDiv.innerHTML = inputHTML;
});
// Event listener for the ‘Create Shape’ button
document.getElementById(‘createShape’).addEventListener(‘click’, function() {
const shapeType = document.getElementById(‘shapeSelect’).value;
const shapeInfoDiv = document.getElementById(‘shapeInfo’);
let shape;
switch(shapeType) {
case ‘circle’:
const radius = document.getElementById(‘radiusInput’).value;
shape = new Circle(radius);
break;
case ‘square’:
const sideLength = document.getElementById(‘sideLengthInput’).value;
shape = new Square(sideLength);
break;
}
if(shape) {
shapeInfoDiv.innerHTML = shape.displayInfo() + `Area: ${shape.area().toFixed(2)}<br>Perimeter: ${shape.perimeter().toFixed(2)}`;
} else {
shapeInfoDiv.innerHTML = “Please select a shape and enter dimensions.”;
}
});
چرا توابع/کلاس های سازنده مفید هستند؟
- استفاده مجدد و کارایی کد: با تعریف یک سازنده Shape عمومی و سازنده های خاص مانند Circle و Square، می توانیم چندین نمونه از این اشکال را بدون تکرار کد ایجاد کنیم. هر نمونه شکل جدید به طور خودکار به روش های تعریف شده در سازنده و نمونه اولیه خود دسترسی خواهد داشت.
- مقیاس پذیری: اگر تصمیم به معرفی یک شکل جدید مانند مثلث داشته باشیم، می توانیم به سادگی بدون تغییر شکل های موجود، سازنده جدیدی برای آن تعریف کنیم. این باعث می شود برنامه ما به راحتی گسترش یابد.
- قابلیت نگهداری: با ویژگی ها و روش های محصور شده در سازنده ها و نمونه های اولیه، نگهداری و به روز رسانی کد آسان تر است. به عنوان مثال، تغییرات در نمونه اولیه Circle، به طور خودکار برای همه نمونه های Circle اعمال می شود.
- سازماندهی: سازنده ها و نمونه های اولیه به سازماندهی کد مربوط به اشیاء خاص کمک می کنند و آن را واضح تر و ماژولارتر می کنند.
این مثال نشان می دهد که چگونه توابع وراثت و سازنده مبتنی بر نمونه اولیه جاوا اسکریپت ایجاد برنامه های کاربردی وب پویا، مقیاس پذیر و قابل نگهداری را تسهیل می کند.
کلاسهای جاوا اسکریپت
بیایید نگاه دقیق تری به کلاسهای جاوا اسکریپت بیندازیم و آنها را با دیدگاهی تازه و مثالهای متمایز دوباره تصور کنیم. این نه تنها درک واضحتری از کلاسها و نقش آنها در جاوا اسکریپت ارائه میکند، بلکه کاربرد عملی آنها را با نمونههای کد کامل همراه با تفسیر نشان میدهد.
مقدمه ای بر کلاس های جاوا اسکریپت
کلاسها در جاوا اسکریپت بهعنوان نقشهای برای ایجاد اشیایی عمل میکنند که ویژگیها و روشهای مشابهی دارند. در حالی که جاوا اسکریپت مبتنی بر نمونه اولیه باقی میماند، کلاسها برای تولید نمونههای شی که به همان ساختار میپیوندند، نحو سنتیتر و قابل خواندنتری ارائه میدهند. این لایه های انتزاعی بر روی وراثت مبتنی بر نمونه اولیه موجود، ایجاد و وراثت شی را ساده می کند.
درک کلاس ها و سازندگان
کلمه کلیدی class یک کلاس را معرفی می کند. به عنوان مثال، یک کلاس ساده که یک کتاب را نشان می دهد در نظر بگیرید:
// Defining a class
class Book {
constructor(title, author) {
this.title = title;
this.author = author;
}
// Method to display book information
displayInfo() {
console.log(`”${this.title}” by ${this.author}`);
}
}
// Creating an instance of Book
const myBook = new Book(“1984”, “George Orwell”);
myBook.displayInfo(); // Output: “1984” by George Orwell
این مثال یک کلاس Book را با ویژگی هایی برای عنوان و نویسنده کتاب تعریف می کند. متد سازنده این خصوصیات را با ایجاد یک نمونه Book جدید مقدار دهی اولیه می کند و متد displayInfo جزئیات کتاب را چاپ می کند.
ساده سازی سازندگان
اگر کلاس شما نیاز به مقداردهی اولیه خاصی ندارد، می توانید سازنده را حذف کنید. جاوا اسکریپت یک سازنده پیش فرض در چنین مواردی ارائه می دهد:
class Animal {
sleep() {
console.log(“Sleeping…”);
}
}
const cat = new Animal();
cat.sleep(); // Output: Sleeping…
اجرای وراثت
وراثت به یک کلاس اجازه می دهد تا ویژگی ها و متدها را از کلاس دیگر به ارث ببرد. برای رسیدن به این هدف از کلمه کلیدی extends استفاده کنید:
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
}
// Defining a subclass
class Student extends Person {
constructor(name, grade) {
super(name); // Call the parent class constructor
this.grade = grade;
}
// Extending functionality
study() {
console.log(`${this.name} is studying.`);
}
}
const student = new Student(“Alice”, “A”);
student.greet(); // Hello, my name is Alice.
student.study(); // Alice is studying.
در این مثال، Student Person را گسترش میدهد و ویژگیها و روشهای آن را به ارث میبرد و در عین حال موارد جدید را معرفی میکند.
کپسوله سازی / Encapsulation با خواص و روش های خصوصی
کلاسهای جاوا اسکریپت از کپسولهسازی پشتیبانی میکنند و به ویژگیها و روشها اجازه میدهند با استفاده از پیشوند # بهعنوان خصوصی علامتگذاری شوند. این دسترسی به آنها را در خارج از کلاس محدود می کند:
class SecretDiary {
#secretMessage;
constructor(message) {
this.#secretMessage = message;
}
// Public method to access the private property
revealSecret() {
console.log(this.#secretMessage);
}
}
const diary = new SecretDiary(“I love JavaScript.”);
diary.revealSecret(); // I love JavaScript.
// diary.#secretMessage; // Uncaught SyntaxError: Private field ‘#secretMessage’ must be declared in an enclosing class
مثال عملی: ماشین حساب شکل
بیایید دانش خود را برای ایجاد یک برنامه کاربردی ساده که مساحت و محیط را برای اشکال مختلف محاسبه می کند، به کار ببریم:
ساختار HTML
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Dynamic Shape Creator</title>
<link rel=”stylesheet” href=”/ITClass01/style.css”>
</head>
<body>
<!– Shape Calculator –>
<label for=”shape”>Choose a shape:</label>
<select id=”shape”>
<option value=”circle”>Circle</option>
<option value=”square”>Square</option>
</select>
<label for=”dimension”>Dimension:</label>
<input id=”dimension” type=”number” placeholder=”Radius or Side Length” />
<button id=”calculate”>Calculate</button>
<div id=”result”></div>
<script src=”script.js”></script>
</body>
</html>
CSS Styling
/* Basic styling for clarity */
body {
font-family: Arial, sans-serif;
}
منطق جاوا اسکریپت
// Shape class definitions
class Shape {
constructor(name) {
this.name = name;
}
}
class Circle extends Shape {
constructor(radius) {
super(“Circle”);
this.radius = radius;
}
area() {
return Math.PI * this.radius ** 2;
}
perimeter() {
return 2 * Math.PI * this.radius;
}
}
class Square extends Shape {
constructor(sideLength) {
super(“Square”);
this.sideLength = sideLength;
}
area() {
return this.sideLength ** 2;
}
perimeter() {
return this.sideLength * 4;
}
}
// Handling user input
document.getElementById(‘calculate’).addEventListener(‘click’, function() {
const shapeType = document.getElementById(‘shape’).value;
const dimension = Number(document.getElementById(‘dimension’).value);
let shape;
switch(shapeType) {
case ‘circle’:
shape = new Circle(dimension);
break;
case ‘square’:
shape = new Square(dimension);
break;
}
// Displaying results
if(shape) {
document.getElementById(‘result’).innerHTML =
`The area of the ${shape.name} is ${shape.area().toFixed(2)}, and the perimeter is ${shape.perimeter().toFixed(2)}.`;
} else {
document.getElementById(‘result’).innerHTML = “Please select a shape and enter its dimension.”;
}
});
این مثال قدرت کلاسهای جاوا اسکریپت را در ایجاد کدهای مدولار، قابل نگهداری و مقیاسپذیر با پیادهسازی یک ماشینحساب شکل تعاملی که به اصول OOP پایبند است، نشان میدهد.
آشنایی با متدها در جاوا اسکریپت
متدها در جاوا اسکریپت اقداماتی هستند که می توان روی اشیاء انجام داد. آنها اساسا توابعی هستند که به اشیا متصل می شوند و به شما امکان می دهند بر روی داده های شی کار کنید، آنها را دستکاری کنید و محاسبات را انجام دهید. درک روش ها برای برنامه نویسی موثر در جاوا اسکریپت بسیار مهم است، زیرا آنها شما را قادر می سازند تا عملیات درون اشیاء را محصور کنید و کد شما را ماژولار تر، قابل استفاده مجدد و قابل نگهداری تر می کند.
مفاهیم کلیدی روش ها:
- کپسولهسازی: روشها به شما این امکان را میدهند که رفتارهای خاصی را با اشیا محصور کنید و اطمینان حاصل کنید که جزئیات داخلی یک شی از بیرون پنهان است و فقط آنچه لازم است را آشکار میکند.
- قابلیت استفاده مجدد: با تعریف روش ها بر روی اشیاء، می توانید از آنها در بخش های مختلف برنامه خود استفاده مجدد کنید و تکرار کد را کاهش دهید.
- روشهای داخلی: جاوا اسکریپت تعداد زیادی از روشهای داخلی را برای اشیاء بومی خود مانند آرایهها، رشتهها و اعداد فراهم میکند و عملیات رایج را بدون نیاز به کتابخانههای خارجی تسهیل میکند.
متدهای اعلام – Declaring Methods
همانطور که در مثال زیر نشان داده شده است، میتوان متدها را با مرتبط کردن یک تابع با یک ویژگی به صورت لفظی شی اعلان کرد:
const person = {
name: ‘John Doe’,
greet: function() {
console.log(`Hello, my name is ${this.name}!`);
}
};
person.greet(); // Outputs: Hello, my name is John Doe!
سینتکس متد ES6
ES6 یک سینتکس مختصر برای تعریف روشها در اشیاء معرفی کرد، و نحو را تمیزتر و شهودیتر کرد:
const person = {
name: ‘Jane Doe’,
greet() {
console.log(`Hello, my name is ${this.name}!`);
}
};
person.greet(); // Outputs: Hello, my name is Jane Doe!
متدهای داخلی شی – Built-in Object Methods
اشیاء داخلی جاوا اسکریپت با روش های خاص خود ارائه می شوند. برای مثال، اشیاء رشتهای متدهایی برای دستکاری دارند، آرایهها متدهایی را برای تکرار و تبدیل و غیره ارائه میدهند.
let str = ‘Hello, World!’;
console.log(str.toUpperCase()); // Outputs: HELLO, WORLD!
متدهای رشته ای – String Methods
let arr = [1, 2, 3];
let doubled = arr.map(num => num * 2);
console.log(doubled); // Outputs: [2, 4, 6]
متدهای آرایه – Array Methods
let arr = [1, 2, 3];
let doubled = arr.map(num => num * 2);
console.log(doubled); // Outputs: [2, 4, 6]
متدهای سفارشی – Custom Methods
شما می توانید روش های خود را برای افزودن قابلیت به اشیاء سفارشی تعریف کنید. این به ویژه برای ایجاد مدل هایی مفید است که موجودیت هایی را در برنامه شما نشان می دهد و عملیات مربوط به آن موجودیت ها را محصور می کند.
مثال: یک شیء شمارنده
const counter = {
count: 0,
increment() {
this.count += 1;
console.log(this.count);
},
reset() {
this.count = 0;
console.log(‘Counter reset to 0’);
}
};
counter.increment(); // Outputs: 1
counter.increment(); // Outputs: 2
counter.reset(); // Outputs: Counter reset to 0
متدها یک جنبه اساسی جاوا اسکریپت هستند که راهی برای کپسوله کردن عملیات درون اشیاء فراهم می کنند. با استفاده از متدها، میتوانید کد تمیزتر و سازمانیافتهتری بنویسید که درک و نگهداری آن آسانتر باشد. خواه از متدهای داخلی برای سادهسازی عملیات رایج استفاده کنید یا متدهای خود را برای محصور کردن منطق کسبوکار تعریف کنید، متدها یک ابزار ضروری در جعبه ابزار برنامهنویس جاوا اسکریپت هستند.
تفاوت بین توابع و متدها در جاوا اسکریپت
تفاوت اصلی بین توابع و متدها در جاوا اسکریپت در نحوه تعریف و فراخوانی آنها نهفته است. یک تابع یک بلوک از کد است که می تواند هنگام فراخوانی اجرا شود، در حالی که یک متد یک تابع مرتبط با یک شی (یا کلاس) است.
- عملکرد: به طور مستقل فراخوانی می شود.
- متد: بر روی یک شیء فراخوانی می شود.
سناریو: یک شیء پست وبلاگ
ما با یک پست وبلاگ ساده یک سناریو ایجاد خواهیم کرد. این شامل HTML برای ساختار صفحه، CSS برای استایل و جاوا اسکریپت برای به روز رسانی پویا محتوا است. جاوا اسکریپت ما شامل یک تابع مستقل و یک متد در یک شی برای نشان دادن تفاوت خواهد بود.
HTML(index.html)
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>Blog Post Example</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<h1 id=”postTitle”></h1>
<p id=”postContent”></p>
<button id=”updateContent”>Update Content</button>
<script src=”script.js”></script>
</body>
</html>
CSS Style (Style.css)
/* Basic styling for clarity */
body {
font-family: Arial, sans-serif;
margin: 40px;
}
h1 {
color: navy;
}
button {
margin-top: 20px;
padding: 10px;
}
JavaScript (script.js)
// Object with a method
const blogPost = {
title: “JavaScript Functions vs Methods”,
content: “A function is called independently, while a method is associated with an object.”,
// Method to display blog post details
display() {
document.getElementById(“postTitle”).textContent = this.title;
document.getElementById(“postContent”).textContent = this.content;
}
};
// Standalone function to update content
function updateBlogContent() {
blogPost.content += ” This is an added sentence to demonstrate updating content.”;
blogPost.display(); // Calls the method within the object
}
// Initial display using the method
blogPost.display();
// Event listener for button to invoke the standalone function
document.getElementById(“updateContent”).addEventListener(“click”, updateBlogContent);
توضیح گام به گام:
- راه اندازی HTML: ما یک طرح صفحه وب ساده با عنوان (<h1>)، محتوا (<p>) و یک دکمه برای به روز رسانی محتوا ایجاد می کنیم.
- استایل CSS: سبک های پایه برای وضوح بصری اعمال می شوند.
- عملکرد جاوا اسکریپت:
- تعریف شی: شی blogPost شامل عنوان، محتوا و روش نمایش است که صفحه وب را با عنوان و محتوا به روز می کند.
- روش: blogPost.display یک متد است زیرا درون شیء blogPost تعریف شده و فراخوانی شده است. این عناصر HTML را با عنوان و محتوای پست وبلاگ به روز می کند.
- عملکرد مستقل: updateBlogContent یک تابع معمولی است که ویژگی محتوای blogPost را تغییر می دهد و سپس روش نمایش را برای به روز رسانی صفحه وب فراخوانی می کند. این یک تابع مستقل در تعامل با یک روش شی را نشان می دهد.
- شنونده رویداد: به دکمه اضافه شده است، هنگام کلیک کردن، تابع updateBlogContent را فراخوانی می کند و نشان می دهد که چگونه می توان از یک تابع مستقل برای راه اندازی تماس های روش شی استفاده کرد.
نتیجه:
این سناریو تمایز عملکردی بین توابع و روشهای مستقل در جاوا اسکریپت را نشان میدهد. توابع مستقل وظایفی را انجام می دهند و می توانند به طور مستقل فراخوانی شوند، در حالی که متدها به اشیاء (یا کلاس ها) گره خورده اند و بر روی داده ها یا وضعیت آنها کار می کنند. هر دو نقش مهمی در برنامه نویسی جاوا اسکریپت دارند و کدهای ساختاریافته و سازمان یافته را تسهیل می کنند.
آشنایی با JSON در جاوا اسکریپت
نمادگذاری شی جاوا اسکریپت – (JavaScript Object Notation (JSON یک فرمت شناخته شده جهانی برای تبادل و ذخیره داده های ساخت یافته است. این سینتکس خود را از جاوا اسکریپت مشتق می کند، اما به طور مستقل عمل می کند و امکان تبادل یکپارچه داده ها را بین کلاینت ها و سرورها یا بین اجزای مختلف یک برنامه وب فراهم می کند.
ماهیت JSON
JSON اساسا یک قالب متنی است که ساختار اشیاء جاوا اسکریپت را تقلید می کند. این برای خوانایی انسان و سهولت استفاده در زبان های برنامه نویسی طراحی شده است، و آن را به فرمت قابل استفاده برای API های وب و فایل های پیکربندی تبدیل می کند.
ویژگی های کلیدی JSON:
- مبتنی بر متن: JSON صرفاً متنی است و به راحتی توسط انسان قابل خواندن است.
- Language Agnostic: با وجود منشأ جاوا اسکریپت، JSON را می توان با بسیاری از زبان های برنامه نویسی استفاده کرد.
- داده های ساختاریافته: از آرایه ها، اشیا، رشته ها، اعداد، بولی ها و تهی پشتیبانی می کند.
کار با JSON در جاوا اسکریپت
جاوا اسکریپت یک شی JSON را با دو روش مهم ارائه می دهد:
- JSON.parse(): یک رشته JSON را به یک شی جاوا اسکریپت تبدیل می کند.
- JSON.stringify(): یک شی جاوا اسکریپت را به یک رشته JSON تبدیل می کند.
این متدها برای کار با دادههای JSON ضروری هستند، چه آنها را از سرور دریافت کنید و چه از مشتری ارسال کنید.
مثال: تجزیه / Parsing JSON
تصور کنید یک رشته JSON از سروری دریافت کنید که حاوی اطلاعاتی درباره یک کتاب است:
// JSON string
‘{“title”: “The Hitchhiker’s Guide to the Galaxy”, “author”: “Douglas Adams”}’
برای دسترسی به این داده ها در جاوا اسکریپت، آن را به این صورت تجزیه کنید:
// Parsing the JSON string
const bookData = JSON.parse(‘{“title”: “The Hitchhiker’s Guide to the Galaxy”, “author”: “Douglas Adams”}’);
console.log(bookData.title); // Outputs: The Hitchhiker’s Guide to the Galaxy
مثال: ایجاد JSON
برعکس، اگر یک شی جاوا اسکریپت به نمایندگی از یک کاربر دارید و باید این داده ها را به یک سرور ارسال کنید، آن را به یک رشته JSON تبدیل می کنید:
// JavaScript object
const user = {
name: “Jane Doe”,
age: 28
};
// Converting the object to a JSON string
const userJSON = JSON.stringify(user);
// The result can be sent to a server
console.log(userJSON); // Outputs: {“name”:”Jane Doe”,”age”:28}
کاربرد عملی: ساخت رابط کاربری
بیایید با ایجاد یک رابط کاربری ساده که اطلاعات فچ شده از یک فایل JSON را نمایش می دهد، آنچه را که در مورد JSON آموخته ایم اعمال کنیم.
ساختار HTML
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Dynamic Shape Creator</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<div id=”userInfo”></div>
<div id=”result”></div>
<script src=”script.js”></script>
</body>
</html>
فایل جاوا اسکریپت
// Fetching user data from a JSON file
fetch(‘user.json’)
.then(response => response.json()) // Convert the response to JSON
.then(data => {
// Displaying the user info
document.getElementById(‘userInfo’).innerHTML = `<p>Name: ${data.name}</p><p>Age: ${data.age}</p>`;
});
فایل user.json شامل:
{
“name”: “John Doe”,
“age”: 30
}
قطعه کد داده های کاربر را فچ می کند، JSON را تجزیه می کند و به صورت پویا نام و سن کاربر را در سند HTML درج می کند.
JSON نقشی اساسی در توسعه وب مدرن ایفا می کند و انتقال داده ها را در قالبی قابل خواندن تسهیل می کند. ادغام آن با جاوا اسکریپت از طریق متدهای تجزیه و رشتهبندی شی JSON به توسعهدهندگان اجازه میدهد تا بدون دردسر دادهها را سریالسازی و سریالزدایی کنند و از جریان روان دادهها در برنامههای کاربردی وب اطمینان حاصل کنند.
نتیجه:
ساخت اشیاء با جاوا اسکریپت: نمایش ساده محصول تجارت الکترونیک
در این سناریو، ما با استفاده از HTML، CSS، جاوا اسکریپت و JSON یک نمایشگر ساده محصول تجارت الکترونیک ایجاد می کنیم. هدف ما تمرین ساختن و دستکاری اشیا و تولید پویا کارت های محصول در یک صفحه وب است.
شرح سناریو
یک فروشگاه اینترنتی را تصور کنید که محصولات مختلفی را به فروش می رساند. ما چند محصول از جمله نام، قیمت و تصاویر را در صفحه خود نمایش خواهیم داد. ما هر محصول را به عنوان یک شی تعریف می کنیم و از یک آرایه برای ذخیره چندین محصول استفاده می کنیم. سپس به صورت پویا محتوای HTML تولید می کنیم تا این محصولات را به صورت کارت در صفحه وب خود نمایش دهیم.
دستورالعمل های گام به گام
HTML (index.html)
ساختار اصلی صفحه را ایجاد کنید.
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>Simple E-Commerce Display</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<h1>Featured Products</h1>
<div id=”productContainer”></div>
<script src=”script.js”></script>
</body>
</html>
CSS (style.css)
برای اینکه کارت های محصول ما مرتب به نظر برسند، سبک هایی اضافه کنید.
/* Basic page styling */
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f4f4f4;
}
h1 {
color: #333;
}
/* Styling for product cards */
.product-card {
background-color: white;
border: 1px solid #ddd;
padding: 10px;
margin-bottom: 20px;
width: calc(33% – 20px);
float: left;
margin-right: 20px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.product-image img {
max-width: 100%;
height: auto;
}
.product-name, .product-price {
margin: 10px 0;
}
عملکرد جاوا اسکریپت (script.js)
اشیاء محصول را تعریف کنید و کارت های محصول را به صورت پویا تولید کنید:
// Sample product data in JSON format
const productsJSON = `[
{
“name”: “Laptop”,
“price”: “$999”,
“image”: “laptop.png”
},
{
“name”: “Smartphone”,
“price”: “$499”,
“image”: “smartphone.png”
},
{
“name”: “Headphones”,
“price”: “$199”,
“image”: “headphones.png”
}
]`;
// Parse JSON to JavaScript object
const products = JSON.parse(productsJSON);
// Function to generate product cards
function displayProducts(products) {
const container = document.getElementById(‘productContainer’);
products.forEach(product => {
// Creating product card elements
const card = document.createElement(‘div’);
card.className = ‘product-card’;
const image = document.createElement(‘div’);
image.className = ‘product-image’;
image.innerHTML = `<img src=”${product.image}” alt=”${product.name}”>`;
const name = document.createElement(‘h2’);
name.className = ‘product-name’;
name.textContent = product.name;
const price = document.createElement(‘div’);
price.className = ‘product-price’;
price.textContent = product.price;
// Appending elements to card and then card to container
card.appendChild(image);
card.appendChild(name);
card.appendChild(price);
container.appendChild(card);
});
}
// Call displayProducts to generate product cards
displayProducts(products);
توضیح:
- HTML: ما یک ظرف <div> راه اندازی کردیم که در آن کارت های محصول ما نمایش داده می شود.
- CSS: یک ظاهر طراحی برای صفحه و کارت های محصول ارائه می دهد و آنها را به صورت شبکه ای از کارت ها نشان می دهد.
- جاوا اسکریپت:
- ما با تعریف یک رشته JSON که محصولات ما را نشان می دهد شروع می کنیم.
- ما این JSON را به یک شی جاوا اسکریپت تجزیه می کنیم تا بتوانیم با آن کار کنیم.
- تابع displayProducts محصولات ما را می گیرد و به صورت پویا عناصر HTML را برای هر محصول ایجاد می کند و جزئیات مربوطه را از اشیاء محصول ما درج می کند.
- در نهایت برای نمایش محصولات در صفحه ما این تابع را فراخوانی می کنیم.
نتیجه:
از طریق این تمرین، نحوه ساخت اشیاء در جاوا اسکریپت و استفاده از آنها برای تولید پویا محتوا در یک صفحه وب را مشاهده کرده اید. این الگو سنگ بنای توسعه وب مدرن است که به برنامه های کاربردی وب پویا و تعاملی اجازه می دهد.
Asynchronous & Synchronous Javascript
آشنایی با جاوا اسکریپت ناهمزمان / Asynchronous
در دنیای برنامه نویسی، به ویژه در توسعه وب، جاوا اسکریپت ناهمزمان سنگ بنای است که به ما امکان می دهد تا کارهایی را که ممکن است مدتی طول بکشد – مانند فچ کردن داده ها از یک API خارجی – بدون فریز کردن رابط کاربری انجام دهیم. این مقاله به بررسی چیستی جاوا اسکریپت ناهمزمان میپردازد، چرا به آن نیاز است، و روشهای مدرن برای مدیریت مؤثر عملیات ناهمزمان را معرفی میکند.
چرا جاوا اسکریپت ناهمزمان؟
جاوا اسکریپت، ذاتاً تک رشته ای است، به این معنی که فقط می تواند یک عملیات را در هر زمان و به ترتیب معین اجرا کند. این مشخصه می تواند منجر به مشکلات عملکردی در هنگام اجرای وظایفی شود که تکمیل آنها زمان قابل توجهی را می طلبد، مانند دانلود یک تصویر یا جستجو در پایگاه داده. این عملیات مانع از اجرای جاوا اسکریپت بعدی می شود که منجر به تجربه کاربری ضعیف می شود.
جاوا اسکریپت ناهمزمان با اجازه دادن به اجرای وظایف طولانی مدت در پسزمینه، این مشکل را برطرف میکند و موتور جاوا اسکریپت را قادر میسازد تا کارهای دیگر را در حالی که منتظر تکمیل عملیات ناهمزمان است، اجرا کند.
تکامل جاوا اسکریپت ناهمزمان
در ابتدا جاوا اسکریپت عملیات ناهمزمان را از طریق توابع پاسخ به تماس انجام می داد. با این حال، این رویکرد اغلب به «جهنم پاسخ به تماس» منجر میشد، جایی که تماسهای تودرتو خواندن و نگهداری کد را دشوار میکرد.
برای بهبود این امر، جاوا اسکریپت Promises را معرفی کرد، اشیایی که نشان دهنده تکمیل یا شکست نهایی یک عملیات ناهمزمان هستند. Promises کد ناهمزمان خواناتر را با مدیریت خطا آسان تر می دهد.
علاوه بر این، نحو ناهمزمان/انتظار معرفی شد، که باعث میشود کدهای ناهمزمان بیشتر شبیه کد همزمان به نظر برسند و رفتار کنند و خوانایی و قابلیت نگهداری را افزایش دهند.
جاوا اسکریپت ناهمزمان در عمل
بیایید یک سناریوی ساده را در نظر بگیریم که در آن باید دادههای کاربر را از یک API فچ کنیم و آن را در کنسول ثبت کنیم.
استفاده از Fetch API با Promises:
fetch(‘https://api.example.com/users/1’)
.then(response => response.json())
.then(user => console.log(user))
.catch(error => console.error(“Failed to fetch user:”, error));
استفاده از Async/Await for Cleaner Syntax:
async function fetchUserData() {
try {
const response = await fetch(‘https://api.example.com/users/1’);
const user = await response.json();
console.log(user);
} catch (error) {
console.error(“Failed to fetch user:”, error);
}
}
fetchUserData();
تمرین عملی: ایجاد یک رابط کاربری برای داده های API
بیایید با ایجاد سناریویی که در آن دادههای کاربر را از یک API ساختگی فچ کرده و در صفحه وب خود نمایش میدهیم، درک خود را از جاوا اسکریپت ناهمزمان افزایش دهیم. این تمرین به نشان دادن قدرت عملیات ناهمزمان در یک زمینه دنیای واقعی کمک خواهد کرد.
سناریو: نمایش داده های کاربر با کلیک روی دکمه
هدف ما ایجاد یک صفحه وب ساده است که با کلیک روی یک دکمه، دادههای کاربر را از یک API خارجی فچ و نمایش میدهد. ما از Fetch API در کنار syntax async/wait برای کدهای ناهمزمان تمیز و خوانا استفاده خواهیم کرد.
مرحله 1: تنظیم HTML
ساختار HTML ما شامل یک دکمه برای راه اندازی عملیات فچ کردن داده ها و یک عنصر <div> برای نمایش داده های فچ شده است.
ساختار HTML:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>Fetch User Data</title>
</head>
<body>
<button id=”fetchButton”>Fetch User Data</button>
<div id=”userData”></div>
<script src=”script.js”></script>
</body>
</html>
عنصر <button> برای شروع عملیات فچ استفاده خواهد شد. عنصر <div> (id=”userData”) جایی است که داده های فچ شده خود را نمایش خواهیم داد.
مرحله 2: اضافه کردن سبک با CSS
بیایید یک استایل اولیه اضافه کنیم تا ارائه داده هایمان کمی جذاب تر شود.
#userData {
margin-top: 20px;
padding: 10px;
background-color: #f0f0f0;
border-radius: 5px;
}
ما تعدادی حاشیه، بالشتک، رنگ پسزمینه و گوشههای گرد را برای ظرف ارائه میکنیم که دادههای کاربر را نمایش میدهد.
مرحله 3: فچ و نمایش داده ها با جاوا اسکریپت
حال، اجازه دهید جاوا اسکریپتی را بنویسیم که دادههای کاربر را به صورت ناهمزمان دریافت میکند و آن را در داخل ظرف <div> ما نمایش میدهد.
document.getElementById(‘fetchButton’).addEventListener(‘click’, async () => {
const userDataContainer = document.getElementById(‘userData’);
// Displaying a loading message
userDataContainer.textContent = ‘Loading…’;
try {
// Fetching user data from a mock API endpoint
const response = await fetch(‘https://jsonplaceholder.typicode.com/users/1’);
const user = await response.json();
// Displaying the fetched user name and email
userDataContainer.textContent = `Name: ${user.name}, Email: ${user.email}`;
} catch (error) {
// Handling any errors that occur during the fetch operation
userDataContainer.textContent = ‘Failed to fetch user data.’;
console.error(“Fetch error:”, error);
}
});
- ما یک شنونده رویداد به دکمه خود اضافه می کنیم که با کلیک کردن فعال می شود.
- ما از دستور async/wait برای فچ دادههای کاربر از یک متغیر API استفاده میکنیم. این رویکرد کد ما را تمیز و خوانا نگه می دارد.
- بلوک try…catch هرگونه خطایی را که ممکن است در حین عملیات فچ رخ دهد کنترل میکند و اطمینان میدهد که برنامه ما قوی باقی میماند.
نتیجه
این سناریو قدرت جاوا اسکریپت ناهمزمان را در توسعه وب نشان می دهد. با استفاده از Fetch API با syntax async/wait، میتوانیم درخواستهای وب را به صورت ناهمزمان انجام دهیم و برنامههای وب خود را پاسخگو و سریع نگه داریم. ساختار try…catch مدیریت خطا را بیشتر می کند و کد ما را قابل اطمینان تر و نگهداری آسان تر می کند.
با API های مختلف آزمایش کنید و راه های مختلفی را برای بهبود تجربه کاربر با استفاده از جاوا اسکریپت ناهمزمان در پروژه های خود کاوش کنید.
برنامه نویسی ناهمزمان در جاوا اسکریپت توسعه برنامه های کاربردی وب سریع و پاسخگو را امکان پذیر می کند. درک و استفاده مؤثر از جاوا اسکریپت ناهمزمان، از جمله Promises و async/wait، برای توسعه دهندگان وب مدرن برای ایجاد تجربیات کاربر یکپارچه ضروری است.
Synchronous Programming
برنامه نویسی سنکرون چیست؟
برنامه نویسی همزمان در جاوا اسکریپت (یا در برنامه نویسی به طور کلی) به یک رویکرد متوالی برای اجرای کد اشاره دارد. در یک مدل برنامه نویسی همزمان، وظایف یکی پس از دیگری اجرا می شوند. هر کار قبل از اجرا منتظر می ماند تا کار قبلی تمام شود. این به این معنی است که اگر یک عملیات خاص برای کامل شدن زمان زیادی طول بکشد (مانند خواندن یک فایل از دیسک یا پرس و جو از یک پایگاه داده)، کارهای بعدی باید تا پایان عملیات منتظر بمانند، که به طور بالقوه منجر به مسدود کردن رفتار و یک برنامه یا برنامه کاربردی کمتر پاسخگو می شود.
در اینجا یک تشبیه ساده وجود دارد: تصور کنید در یک صف کافی شاپ هستید. هر مشتری قهوه خود را سفارش می دهد، منتظر می ماند تا آن را درست کند و به او تحویل دهد و تنها پس از آن مشتری بعدی سفارش خود را شروع می کند. این فرآیند خطی و متوالی است و هر مرحله قبل از ادامه در انتظار تکمیل مرحله قبلی است.
در جاوا اسکریپت، زمانی که کد همزمان را اجرا می کنید، هر دستور قبل از رفتن به دستور بعدی، اجرای خود را کامل می کند. در اینجا یک مثال اساسی برای نشان دادن اجرای کد همزمان آورده شده است:
console.log(‘First task starts’);
// Simulate a task that takes time, for example, a loop
for(let i = 0; i < 1000000000; i++) {}
console.log(‘First task ends and second task starts’);
// Second task
console.log(‘Second task ends’);
در این مثال، جاوا اسکریپت قبل از رفتن به دستور بعدی console.log منتظر می ماند تا حلقه کامل شود. این رفتار تضمین می کند که عملیات ها به ترتیبی که نوشته شده اند قابل پیش بینی و اجرا می شوند. با این حال، میتواند منجر به ناکارآمدی شود، بهویژه زمانی که با عملیاتهایی که زمانبر هستند یا به منابع خارجی مانند درخواستهای شبکه وابسته هستند، سر و کار داریم.
ماهیت همزمان اجرا در چنین سناریوهایی می تواند برنامه را کند یا بی پاسخ کند، به خصوص در زمینه توسعه وب که تجربه کاربر بسیار مهم است. به همین دلیل است که الگوهای برنامه نویسی ناهمزمان اغلب برای عملیاتی که شامل تاخیر یا انتظار قابل توجه است ترجیح داده می شود و به برنامه اجازه می دهد تا با اجرای وظایف دیگر در حالی که منتظر تکمیل این عملیات است پاسخگو باقی بماند.
تفاوت کلیدی بین برنامهنویسی ناهمزمان و همزمان
تفاوت کلیدی بین برنامهنویسی ناهمزمان و همزمان در نحوه مدیریت عملیاتهایی است که تکمیل آنها به زمان نیاز دارد، به ویژه آنهایی که شامل انتظار هستند، مانند درخواستهای شبکه، عملیات فایل یا تایمر. در اینجا به تفکیک تفاوت ها، به دنبال یک مثال و بهترین شیوه ها آمده است:
برنامه نویسی همزمان
- جریان اجرا: عملیات به ترتیب و یکی پس از دیگری اجرا می شوند. هر عملیات باید قبل از شروع عملیات بعدی کامل شود.
- مسدود کردن: اگر تکمیل یک عملیات به زمان نیاز داشته باشد (مثلاً خواندن یک فایل بزرگ)، اجرای برنامه مسدود میشود، به این معنی که تا زمانی که عملیات فعلی تمام نشود، نمیتوان به عملیات بعدی ادامه داد.
- سادگی: درک و دنبال کردن آن آسانتر است، زیرا اجرای کد با ترتیب نوشته شدن کد مطابقت دارد.
- موارد استفاده: بهترین گزینه برای عملیات سریع یا جاهایی که کارها باید با ترتیب خاصی بدون نیاز به همزمانی کامل شوند.
برنامه نویسی ناهمزمان
- جریان اجرا: عملیاتی که تکمیل آنها زمان بر است جدا از جریان اصلی برنامه اجرا می شود و به برنامه اجازه می دهد تا به اجرای وظایف دیگر ادامه دهد.
- Non-Blocking: عملیات طولانی مدت به گونه ای انجام می شود که اجرای برنامه را مسدود نمی کند. سایر عملیات ها همچنان می توانند در حین انتظار برای نتیجه اجرا شوند.
- پیچیدگی: به دلیل تماسهای برگشتی، وعدهها و دستور ناهمگام/انتظار میتواند برای درک و پیادهسازی پیچیدهتر باشد. مدیریت خطا و اشکال زدایی نیز می تواند چالش برانگیزتر باشد.
- موارد استفاده: ایده آل برای عملیاتی که شامل انتظار است، مانند درخواست های وب API، ورودی/خروجی فایل یا هر گونه ارتباط شبکه ای. برای افزایش عملکرد و پاسخگویی در برنامه ها عالی است.
مثال
همزمان / Synchronous:
console.log(‘Start downloading image…’);
// Simulate image download (blocking)
for(let i = 0; i < 1000000000; i++) {}
console.log(‘Image downloaded.’);
// This next line has to wait until the image download simulation is complete
console.log(‘Start processing image…’);
نامتقارن / Asynchronous:
console.log(‘Start downloading image…’);
setTimeout(() => {
// Simulate image download (non-blocking)
console.log(‘Image downloaded.’);
}, 2000);
// This next line runs immediately, without waiting for the image download simulation
console.log(‘Start processing image…’);
Best Practices Asynchronous
- از متدهای ناهمزمان برای عملیات ورودی/خروجی استفاده کنید: برای عملیاتهایی مانند درخواستهای شبکه، وظایف سیستم فایل، و هرگونه عملیات محدود به ورودی/خروجی، از متدهای ناهمزمان برای جلوگیری از مسدود کردن رشته اصلی اجرا استفاده کنید، در نتیجه پاسخدهی و عملکرد برنامهتان را بهبود میبخشید.
- Prefer Promises and Async/Await Over Callbacks: Callbacks می تواند منجر به جهنم برگشت به تماس شود و خواندن و نگهداری کد را سخت کند. Promises و syntax async/wait متدی تمیزتر و خواناتر برای مدیریت عملیات ناهمزمان ارائه می دهد.
- مدیریت خطا: از بلوکهای try/catch با async/wait استفاده کنید تا خطاها را به خوبی مدیریت کنید. هنگام استفاده از وعدهها، مطمئن شوید که خطاها را شناسایی کنید تا از کنترل نشدن آنها جلوگیری کنید.
- همزمانی: برای بهینهسازی عملکرد، از ویژگیهایی مانند Promise.all برای اجرای چندین عملیات ناهمزمان بهطور همزمان و نه متوالی استفاده کنید.
- درک زمان و نحوه استفاده از برنامه نویسی ناهمزمان و همزمان برای توسعه برنامه های کاربردی جاوا اسکریپت کارآمد، پاسخگو و قابل نگهداری بسیار مهم است.
Event Handlers چیست؟
کنترلکنندههای رویداد، توابعی در جاوا اسکریپت هستند که در پاسخ به رویدادهای خاصی که در یک برنامه وب رخ میدهند، اجرا میشوند. این رویدادها میتواند هر چیزی باشد، از کلیک کاربر روی دکمه، ارسال فرم، حرکت دادن ماوس تا رویدادهای پیچیدهتر ایجاد شده توسط سیستم. کنترلکنندههای رویداد نقش مهمی در تعاملی کردن صفحات وب و پاسخگویی به اقدامات کاربر دارند.
نقش آنها در جاوا اسکریپت
- تعامل کاربر: آنها صفحات وب را با اجرای کد در پاسخ به اقدامات کاربر تعاملی می کنند.
- اجرای ناهمزمان: کنترل کننده های رویداد معمولاً به صورت ناهمزمان اجرا می شوند و به رویدادهایی که در زمان های نامشخص رخ می دهند پاسخ می دهند.
- دستکاری DOM: آنها اغلب مدل شیء سند (DOM) را بر اساس اقدامات کاربر، مانند نمایش یا پنهان کردن عناصر، اصلاح محتوا و غیره دستکاری می کنند.
- اعتبار سنجی و فرمها: کنترلکنندههای رویداد برای اعتبارسنجی ورودیهای فرم قبل از ارسال استفاده میشوند.
- انیمیشن و جلوه ها: آنها انیمیشن ها یا جلوه های بصری را در پاسخ به تعاملات کاربر ایجاد می کنند.
سنکرون یا ناهمزمان؟
کنترلکنندههای رویداد طبیعتاً ناهمزمان هستند، زیرا منتظر میمانند تا یک رویداد بدون مسدود کردن اجرای کدهای دیگر اتفاق بیفتد. تابع handler تنها زمانی فراخوانی می شود که رویداد مرتبط با آن فعال شود.
مثال عملی: یک رویداد کلیک ساده
بیایید یک مثال ساده ایجاد کنیم که در آن کلیک کردن روی یک دکمه رنگ یک عنصر div را تغییر میدهد.
مرحله 1: ساختار HTML
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>Event Handler Example</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<button id=”changeColorBtn”>Change Color</button>
<div id=”colorBox”></div>
<script src=”script.js”></script>
</body>
</html>
مرحله 2: CSS برای استایل کردن
/* style.css */
#colorBox {
width: 100px;
height: 100px;
background-color: blue;
}
button {
margin: 20px;
padding: 10px;
}
مرحله 3: جاوا اسکریپت برای مدیریت رویداد
// script.js
document.addEventListener(“DOMContentLoaded”, function() {
// Selecting the button and the div
const button = document.getElementById(‘changeColorBtn’);
const box = document.getElementById(‘colorBox’);
// Defining the event handler function
function changeColor() {
box.style.backgroundColor = box.style.backgroundColor === ‘blue’ ? ‘red’ : ‘blue’;
}
// Assigning the event handler to button’s click event
button.addEventListener(‘click’, changeColor);
});
این کد قبل از انتخاب عناصر و تخصیص کنترل کننده رویداد تا بارگذاری کامل DOM صبر می کند. هنگامی که دکمه کلیک می شود، تابع changeColor اجرا می شود و رنگ پس زمینه div را بین آبی و قرمز تغییر می دهد.
بهترین توصیه ها برای استفاده از رویداد Handlers
- از addEventListener استفاده کنید: به شما امکان می دهد چندین کنترل کننده رویداد را به یک رویداد اضافه کنید و انعطاف پذیری بیشتری را نسبت به ویژگی onclick قدیمی در HTML فراهم می کند.
- جداسازی نگرانی ها: کدهای HTML، CSS و جاوا اسکریپت خود را جدا نگه دارید تا کدهای تمیز و قابل مدیریت را حفظ کنید.
- توابع ناشناس: برای مدیریت رویدادهای ساده و یکبار مصرف، استفاده از توابع ناشناس را مستقیماً در داخل addEventListener در نظر بگیرید.
- Remove Event Listeners: اگر دیگر نیازی به شنونده رویداد نیست، آن را با removeEventListener حذف کنید تا از نشت حافظه جلوگیری شود.
- Delegation رویداد: از تفویض رویداد برای به حداقل رساندن تعداد گردانندگان رویداد استفاده کنید. به وقایع مربوط به یک والدین مشترک به جای فرزندان فردی گوش دهید.
- دسترسپذیری: اطمینان حاصل کنید که کنترلکنندههای رویداد در دسترسپذیری وبسایت شما دخالت نمیکنند. کاربران صفحهکلید و صفحهخوان باید بتوانند با همه عناصر تعاملی تعامل داشته باشند.
مدیریت رویدادها ستون فقرات توسعه وب تعاملی هستند که به توسعه دهندگان اجازه می دهند وب سایت های پاسخگو و کاربر پسند ایجاد کنند.
آشنایی با Promises در جاوا اسکریپت
وعده ها / Promise برای مدیریت عملیات ناهمزمان در جاوا اسکریپت اساسی هستند. آنها یک مکانیسم قوی برای مدیریت نتایج و خطاهای عملیات ناهمزمان، مانند درخواستهای شبکه، عملیات فایل یا تایمر ارائه میدهند. بیایید وعده ها، موارد استفاده آنها و نحوه استفاده از آنها را با مثال های عملی بررسی کنیم.
Promise در جاوا اسکریپت یک شی / Object است که نشان دهنده تکمیل یا شکست نهایی یک عملیات ناهمزمان / Asynchronous است. این به شما اجازه می دهد تا کنترل کننده ها را با ارزش موفقیت یا دلیل شکست یک اقدام ناهمزمان مرتبط کنید. این به متدهای ناهمزمان اجازه میدهد مقادیری مانند متدهای همزمان را برگردانند: به جای اینکه بلافاصله مقدار نهایی را برگرداند، متد ناهمزمان وعدهای را برای ارائه مقدار در نقطهای در آینده برمیگرداند.
در کجا از وعده ها استفاده می شود؟
Promises در سناریوهایی استفاده می شود که در آن شما نیاز به انجام عملیات ناهمزمان دارید، مانند:
- فچ کردن داده ها از سرور با استفاده از Fetch API.
- انجام عملیات فایل در Node.js.
- بسته بندی API های قدیمی مبتنی بر تماس در وعده هایی برای قابلیت استفاده و کنترل بهتر.
چرا وعده ها مهم هستند؟
- غیر مسدود کردن: Promises به جاوا اسکریپت اجازه می دهد تا عملیات طولانی را در پس زمینه انجام دهد و پاسخگویی برنامه های وب را بهبود بخشد.
- مدیریت خطای ساده شده: با .then() برای موفقیت و .catch() برای خطاها، وعده ها فرآیند کشف و رسیدگی به خطاها را ساده می کنند.
- Cleaner Async Code: وعدهها پیچیدگی کدهای ناهمزمان را کاهش میدهند، از جهنم بازگشت به تماس بدنام جلوگیری میکنند و خواندن و نگهداری کد را آسانتر میکنند.
نحوه استفاده از وعده ها
وعدهها در جاوا اسکریپت بر اساس کمیت طبقهبندی نمیشوند، بلکه بر اساس وضعیت و کاربردشان دستهبندی میشوند. با این حال، چندین مفهوم و روش کلیدی مرتبط با وعده ها وجود دارد که باید با آنها آشنا باشید. در اینجا یک تفکیک وجود دارد:
یک وعده در جاوا اسکریپت می تواند در یکی از سه حالت باشد:
- در انتظار / Pending: حالت اولیه یک قول. نتیجه هنوز مشخص نشده است زیرا عملیات ناهمزمان که وعده نشان می دهد کامل نشده است.
- برآورده شده / Fulfilled: حالت یک وعده که نشان دهنده یک عملیات موفق است. این به این معنی است که عملیات ناهمزمان کامل شده است و وعده اکنون یک مقدار حل شده دارد.
- Rejected: حالت یک وعده که نشان دهنده یک عملیات ناموفق است. این به این معنی است که عملیات ناهمزمان شکست خورده است و قول اکنون دلیلی برای شکست دارد.
- روش های اصلی وعده
چندین روش در خود شی Promise یا یک نمونه قول وجود دارد. درک این موارد به شما کمک می کند تا به طور موثر با وعده ها کار کنید:
- (Promise Constructor () (new Promise: برای ایجاد یک وعده جدید استفاده می شود. سازنده یک تابع مجری می گیرد که با دو تابع Resol و Reject فراخوانی می شود که به ترتیب برای حل یا رد قول استفاده می شود.
- ()then: برای برنامهریزی یک callback استفاده میشود تا زمانی که وعده محقق شد، اجرا شود. همچنین میتوانید برای انجام عملیات ناهمزمان اضافی به ترتیب، روشها را زنجیرهای کنید.
- ()catch: برای برنامهریزی یک تماس برگشتی برای اجرای زمانی که وعده رد میشود استفاده میشود. برای رسیدگی به خطا در زنجیره های وعده استفاده می شود.
- ()final: به شما امکان می دهد بدون توجه به سرنوشت وعده، یک تماس برگشتی را اجرا کنید. این برای پاکسازی منابع یا سایر کارهای نهایی مفید است.
روش های سودمند برای وعده های متعدد
اینها روشهای ایستا در سازنده Promise هستند که در برخورد با وعدههای متعدد کمک میکنند:
- ()Promise.all: یک تکرار از وعدهها را میگیرد و یک وعده واحد را برمیگرداند که زمانی حل میشود که همه وعدههای ورودی حل شوند یا زمانی که تکرار شونده حاوی هیچ وعدهای نباشد. رد می کند به دلیل قول اولی که رد می کند.
- ()Promise.allSettled: شبیه Promise.all است، اما منتظر می ماند تا تمام وعده های ورودی بدون توجه به رد شدن آنها تکمیل شود. با آرایه ای از اشیاء حل می شود که هر کدام نتیجه هر وعده را توصیف می کند.
- ()Promise.race: یک وعده تکراری را می گیرد و یک وعده واحد را برمی گرداند که به محض اینکه یکی از وعده های ورودی تسویه شد (یا حل شود یا رد شود)، با ارزش یا دلیل آن قول تسویه می شود.
- ()Promise.any: مشابه Promise.race، اما تنها پس از رد شدن همه وعدههای ورودی، با یک AggregateError حاوی دلایل رد شدن، رد میشود. به محض رفع هر یک از وعده های ورودی حل می شود.
- ()Promise.resolve: قولی را برمی گرداند که با مقدار داده شده حل شده است. اگر مقدار یک وعده باشد، آن وعده برگردانده می شود.
- ()Promise.reject: قولی را که با دلیل ذکر شده رد شده است برمی گرداند.
Promises یک ویژگی قدرتمند جاوا اسکریپت برای مدیریت عملیات ناهمزمان است. آنها روشی قویتر برای مدیریت کد ناهمزمان در مقایسه با رویکردهای قدیمیتر مبتنی بر تماس ارائه میکنند. درک وضعیتهایی که یک وعده میتواند در آن باشد، و همچنین روشهای موجود برای مدیریت وعدهها، برای برنامهنویسی موثر جاوا اسکریپت، به ویژه هنگام کار با APIهای وب مدرن و الگوهای کد ناهمزمان، بسیار مهم است.
ایجاد و استفاده از وعده ها
یک وعده نشان دهنده تکمیل (failure) نهایی یک عملیات ناهمزمان و مقدار حاصل از آن است. در اینجا نحوه استفاده از آنها آمده است:
ایجاد یک Promise: یک وعده با سازنده Promise که یک تابع مجری می گیرد، نمونه سازی می شود. این تابع بلافاصله توسط اجرای Promise اجرا می شود و دو تابع را به عنوان پارامتر دریافت می کند که به طور سنتی به نام های Resol و Reject نامیده می شود.
const myPromise = new Promise((resolve, reject) => {
// Asynchronous operation here
if (/* operation successful */) {
resolve(value); // Resolves the promise with value
} else {
reject(error); // Rejects the promise with error
}
});
استفاده از Promises: هنگامی که یک قول دارید، میتوانید تماسهای برگشتی را برای رسیدگی به تحقق (then.) یا رد (catch.) به آن متصل کنید.
myPromise.then((value) => {
// Success!
}).catch((error) => {
// An error occurred
});
فچ کردن – Fetch
بیایید از Fetch API برای فچ کردن داده ها از یک URL استفاده کنیم و ببینیم چگونه وعده ها عملیات ناهمزمان را ساده می کنند.
// Fetching a list of products from the given URL
fetch(“https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json”)
.then(response => response.json()) // Parsing the response to JSON
.then(data => console.log(data)) // Logging the data
.catch(error => console.error(‘Fetching error:’, error)); // Handling any errors
در این مثال، fetch() یک وعده را برمی گرداند، که به ما امکان می دهد .then() را برای سناریوهای موفقیت و .catch() را برای مدیریت خطاها زنجیره کنیم.
مدیریت چندین عملیات ناهمزمان
گاهی اوقات، ممکن است لازم باشد چندین عملیات را انجام دهید که به نتایج یکدیگر بستگی ندارد. در چنین مواردی، Promise.all() می تواند فوق العاده مفید باشد زیرا منتظر می ماند تا همه وعده ها حل و فصل شوند.
Promise.all([
fetch(“https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found”),
fetch(“https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json”)
]).then(responses => {
// responses is an array of the response objects from the above URLs
responses.forEach(response => console.log(response.url, response.status));
}).catch(error => {
console.error(‘One or more requests failed:’, error);
});
این مثال تلاش می کند تا داده ها را از دو URL فچ کند. Promise.all() تضمین میکند که ما فقط زمانی ادامه میدهیم که تمام درخواستهای فچ تکمیل شوند و به ما امکان میدهد نتایج را به صورت جمعی مدیریت کنیم.
ایجاد یک وعده جدید:
const myPromise = new Promise((resolve, reject) => {
// Perform some asynchronous operation here
const success = true; // Just a placeholder condition
if (success) {
resolve(‘Operation succeeded’);
} else {
reject(‘Operation failed’);
}
});
// Using the created promise
myPromise
.then(result => console.log(result)) // Logs ‘Operation succeeded’ if successful
.catch(error => console.error(error)); // Logs ‘Operation failed’ if an error occurred
در این کد، myPromise یک شی جدید Promise است. تابع executor در new Promise() بلافاصله اجرا می شود و قرار است در نهایت حل (برای موفقیت) یا reject (برای شکست) را فراخوانی کند.
نتیجه گیری و بهترین شیوه ها
وعده ها به طور قابل توجهی مدیریت کد ناهمزمان را در جاوا اسکریپت ساده می کند. در اینجا برخی از بهترین شیوه ها وجود دارد:
- هنگام رسیدگی به وعدهها، از async/wait برای نحو تمیزتر استفاده کنید.
- همیشه با استفاده از .catch () یا try/catch با async/await، رد وعده ها را مدیریت کنید.
- از Promise.all() برای عملیات ناهمزمان همزمان که به یکدیگر وابسته نیستند استفاده کنید.
مثال: فچ کردن داده های محصول
در این سناریو، ما یک برنامه وب ساده ایجاد می کنیم که داده های محصول را از URL ارائه شده فچ می کند و آن را در صفحه نمایش می دهد. ما از ویژگیهای جاوا اسکریپت مدرن مانند فچ برای بازیابی دادهها، همگامسازی/انتظار برای عملیات ناهمزمان و الگوهای واقعی برای تولید HTML استفاده خواهیم کرد. این برنامه همچنین با CSS برای ارائه جذابتر استایلبندی میشود.
مرحله 1: ساختار HTML را تنظیم کنید
ابتدا یک فایل HTML ایجاد می کنیم که شامل یک محفظه برای محصولات و یک تگ اسکریپت برای گنجاندن کد جاوا اسکریپت ما است.
index.html
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Product Display</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<h1>Product Listings</h1>
<div id=”products” class=”products”></div>
<script src=”script.js”></script>
</body>
</html>
مرحله 2: یک سبک CSS
یک فایل style.css ایجاد کنید.
body {
font-family: Arial, sans-serif;
padding: 20px;
background-color: #f4f4f4;
}
h1 {
color: #333;
}
.products {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.product {
background: white;
padding: 10px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
width: calc(33.333% – 20px);
border-radius: 5px;
}
.product img {
max-width: 100%;
border-radius: 5px;
}
.product h2 {
font-size: 18px;
color: #333;
}
.product p {
font-size: 16px;
color: #666;
}
مرحله 3: فچ و نمایش محصولات با جاوا اسکریپت
در نهایت، ما script.js را برای فچ کردن داده های محصول و نمایش هر محصول در صفحه HTML پیاده سازی می کنیم.
async function fetchProducts() {
try {
const response = await fetch(‘https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json’);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const data = await response.json();
displayProducts(data);
} catch (error) {
console.error(`Could not get products: ${error}`);
}
}
function displayProducts(products) {
const container = document.getElementById(‘products’);
products.forEach(product => {
const productElement = document.createElement(‘div’);
productElement.className = ‘product’;
productElement.innerHTML = `
<img src=”https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/${product.image}” alt=”${product.name}”>
<h2>${product.name}</h2>
<p>$${product.price}</p>
`;
container.appendChild(productElement);
});
}
// Call fetchProducts to load and display the products
fetchProducts();
توضیح کد جاوا اسکریپت:
- تابع Async fetchProducts: این تابع به طور ناهمزمان داده های محصول را از URL داده شده با استفاده از fetch فچ می کند. از انتظار برای تکمیل فچ استفاده میکند، که باعث میشود کد هماهنگ به نظر برسد و خواندن آن آسانتر شود.
- مدیریت خطا: اگر درخواست فچ ناموفق باشد (خطای شبکه یا وضعیت پاسخ درست نیست)، یک خطا پرتاب میشود و در بلوک catch ثبت میشود، جایی که در کنسول ثبت میشود.
- نمایش محصولات: هنگامی که داده ها با موفقیت فچ شد و به JSON تبدیل شد، displayProducts با داده های محصول فچ شده فراخوانی می شود. این تابع بر روی هر محصول تکرار می شود، یک عنصر HTML جدید برای هر یک ایجاد می کند و آن را در DOM قرار می دهد. تصویر، نام و قیمت محصول نمایش داده می شود.
- فراخوانی fetchProducts: در نهایت، ما fetchProducts را فراخوانی می کنیم تا هنگام بارگیری اسکریپت، عملیات فچ را آغاز کنیم.
این مثال نحوه استفاده از ویژگیهای جاوا اسکریپت مدرن را برای فچ دادهها از یک API راه دور و نمایش آن در یک صفحه وب نشان میدهد. ما از async/wait برای کدهای ناهمزمان با خوانایی آسان و الفبای الگو برای تولید پویا HTML بر اساس دادههای فچ شده استفاده کردیم. استفاده از CSS flexbox تضمین می کند که محصولات به خوبی در صفحه چیده شوند.
مقدمه ای بر Web Workers
در توسعه وب مدرن، حفظ یک رابط کاربری روان و پاسخگو در حین انجام عملیات پیچیده می تواند چالش برانگیز باشد. جاوا اسکریپت که تک رشته ای است، در همان رشته رابط کاربری اجرا می شود و آن را مستعد مسدود کردن عملیاتی می کند که می تواند صفحه را مسدود کند. اینجاست که Web Workers وارد عمل میشود و راهحلی قدرتمند را با فعال کردن وظایف به موازات موضوع اصلی ارائه میدهد.
Web Workers چیست؟
Web Workers به شما این امکان را می دهد که عملیات جاوا اسکریپت را در رشته های پس زمینه اجرا کنید و رشته اصلی را برای تعاملات UI آزاد نگه دارید. این اجرای موازی تضمین می کند که وظایف سنگین رابط کاربری را مسدود نمی کند و پاسخگویی برنامه های وب را بهبود می بخشد.
انواع کارگران – Workers
کارگران اختصاص داده شده: کارگران متعهد که به خالق خود گره خورده اند، فقط می توانند با رشته ای که آنها را ایجاد کرده ارتباط برقرار کنند، و آنها را برای تخلیه وظایف خاص و فشرده از رشته اصلی ایده آل می کند.
Shared Workers: این کارگران را می توان با چندین اسکریپت – حتی در پنجره ها یا برگه های مختلف مرورگر – که تعاملات پیچیده تر و به اشتراک گذاری داده ها را تسهیل می کند، قابل دسترسی است.
Service Workers: به عنوان یک پروکسی شبکه عمل میکند، سرویسکاران تجربههای آفلاین غنی، همگامسازی پسزمینه، و اعلانهای فشاری را در میان چیزهای دیگر فعال میکنند. آنها نقش مهمی در توسعه برنامه های وب پیشرو (PWA) دارند.
مثال عملی: Web Workers
بیایید یک مثال مدرن و پاسخگو ایجاد کنیم که استفاده از Web Workers را در یک برنامه وب نشان می دهد. ما یک برنامه ساده خواهیم ساخت که اعداد فیبوناچی را در پس زمینه محاسبه می کند. هدف حفظ یک رابط کاربری پاسخگو حتی در حین انجام وظایف محاسباتی فشرده است.
سناریو: ماشین حساب فیبوناچی با Web Worker
این اپلیکیشن به کاربران اجازه می دهد تا عددی را وارد کنند و عدد فیبوناچی مربوطه را در پس زمینه با استفاده از Web Worker محاسبه می کند. دنباله فیبوناچی به دلیل سادگی انتخاب شده است و به دلیل اینکه محاسبه آن می تواند برای ورودی های بزرگ منابع فشرده باشد، و آن را برای این نمایش ایده آل می کند.
مرحله 1: ساختار پروژه
یک پوشه پروژه با فایل های زیر ایجاد کنید:
- index.html – ساختار HTML برنامه ما.
- style.css – برای استایل دادن به برنامه ما.
- main.js – فایل اصلی جاوا اسکریپت برای تعامل رابط کاربری.
- fibonacciWorker.js – اسکریپت Web Worker که اعداد فیبوناچی را محاسبه می کند.
index.html
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Prime Number Generator</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<h1>Fibonacci Calculator</h1>
<input type=”number” id=”numberInput” placeholder=”Enter a number”>
<button id=”calculateBtn”>Calculate</button>
<div id=”result”>Result will appear here…</div>
<script src=”main.js”></script>
</body>
</html>
Styling (style.css)
body {
font-family: Arial, sans-serif;
text-align: center;
margin-top: 50px;
}
input, button {
font-size: 18px;
padding: 10px;
margin: 5px;
}
#result {
margin-top: 20px;
font-size: 20px;
color: green;
}
منطق موضوع اصلی (main.js)
// Initialize the Web Worker
const worker = new Worker(‘fibonacciWorker.js’);
document.getElementById(‘calculateBtn’).addEventListener(‘click’, function() {
const number = document.getElementById(‘numberInput’).value;
worker.postMessage(number); // Send the number to the worker
document.getElementById(‘result’).textContent = ‘Calculating…’;
});
// Listen for messages from the worker
worker.addEventListener(‘message’, function(event) {
document.getElementById(‘result’).textContent = `Result: ${event.data}`;
});
// Error handling
worker.addEventListener(‘error’, function(event) {
document.getElementById(‘result’).textContent = `Error: ${event.message}`;
});
Worker Thread Logic – منطق موضوع کارگر (fibonacciWorker.js)
self.addEventListener(‘message’, function(event) {
const number = event.data;
const result = calculateFibonacci(number);
self.postMessage(result);
});
function calculateFibonacci(n) {
if (n <= 1) return n;
return calculateFibonacci(n – 1) + calculateFibonacci(n – 2);
}
توضیحات گام به گام:
- راه اندازی HTML: ما یک رابط کاربری ساده با ورودی برای عدد، یک دکمه برای شروع محاسبه و یک div برای نمایش نتیجه تعریف می کنیم.
- CSS Styling: برای بهبود خوانایی و قابلیت استفاده، یک ظاهر طراحی اولیه را برای عناصر UI ما ارائه می دهد.
- Main Thread Logic: Web Worker را راه اندازی می کند و شنوندگان رویداد را برای عناصر UI تنظیم می کند. شماره ورودی را برای پردازش به کارگر می فرستد و نتیجه یا پیام های خطای دریافتی از کارگر را نمایش می دهد.
- Web Worker Logic: به پیام هایی از رشته اصلی گوش می دهد، محاسبه فیبوناچی را انجام می دهد و نتیجه را به رشته اصلی ارسال می کند.
بهترین توصیه ها:
- موارد استفاده: Web Workers برای کارهایی مانند پردازش داده ها، محاسبات پیچیده و سایر عملیاتی که در غیر این صورت رشته UI را مسدود می کنند، ایده آل هستند.
- ارتباطات: کارگران از طریق پیامها با موضوع اصلی ارتباط برقرار میکنند و از کپسولهسازی دادهها و ایمنی رشته اطمینان میدهند.
- محدودیتها: کارگران به DOM دسترسی ندارند و در یک زمینه محدود اجرا میشوند، که آنها را برای محاسبات خارج از رشته UI مناسب میکند.
- از Web Workers برای محاسبات فشرده برای پاسخگو نگه داشتن رابط کاربری استفاده کنید.
- کارگران را زمانی که دیگر برای آزاد کردن منابع لازم نیست خاتمه دهید: worker.terminate();.
- مدیریت خطا: اطمینان حاصل کنید که خطاها را هم در اسکریپت اصلی و هم در اسکریپت کارگر مدیریت می کنید.
- بهینه سازی الگوریتم ها برای عملکرد بهتر، به ویژه در کارگران برای به حداقل رساندن زمان محاسبات.
این مثال نشان میدهد که چگونه میتوان از Web Workers برای انجام محاسبات پیچیده بدون مسدود کردن UI استفاده کرد و تجربه کاربری روان را تضمین کرد.
Web Workers یک مدل قوی برای اجرای وظایف فشرده بدون به خطر انداختن تجربه کاربر ارائه میدهد و آنها را به ابزاری ضروری در جعبه ابزار توسعهدهندگان وب مدرن تبدیل میکند.
نتیجه
همانطور که به پایان سفر خود از طریق جنبه های اساسی HTML، CSS و جاوا اسکریپت می رسیم، مهم است که در مسیری که طی کرده ایم فکر کنیم. از اصول ساختاردهی صفحات وب با HTML گرفته تا سبک سازی آنها با CSS، و در نهایت به افزودن تعامل با جاوا اسکریپت، ما طیف گسترده ای از اصول توسعه وب را پوشش داده ایم که برای هر توسعه دهنده وب مشتاق ضروری است.
اما سفر به اینجا ختم نمی شود. دنیای توسعه وب بسیار گسترده و دائماً در حال تغییر است و استانداردها، چارچوبها و بهترین شیوههای جدید همیشه در حال ظهور هستند. دانشی که به دست آورده اید یک پایه محکم است، اما یادگیری و تمرین مستمر کلید پیشرفت مهارت های شما و به روز ماندن در این زمینه پویا است.
برای کسانی که مشتاق به کاوش عمیق تر و گسترش درک خود از توسعه وب هستند، منابع فراوانی در انتظار است. یک منبع با ارزش ویژه، اسناد وب شبکه توسعه دهنده موزیلا (MDN) است:
MDN Web Docs – JavaScript را یاد بگیرید
MDN Web Docs مخزن گسترده ای از دانش است که آموزش های عمیق، راهنماها و مواد مرجع در HTML، CSS، جاوا اسکریپت و موارد دیگر را ارائه می دهد. چه به دنبال تعمیق درک خود از جاوا اسکریپت، کاوش در موضوعات پیشرفته، یا یادگیری در مورد آخرین فن آوری های وب و API ها هستید، MDN Web Docs یک منبع ضروری است.
به یاد داشته باشید، سفر یادگیری توسعه وب یکی از کاوش و کشف مداوم است. به طور منظم تمرین کنید، پروژه بسازید، و از آزمایش کردن و اشتباه کردن نترسید – همه اینها بخشی از فرآیند یادگیری است. با جامعه توسعهدهنده تعامل داشته باشید، در پروژههای منبع باز مشارکت داشته باشید و مرزهای آنچه را که میتوانید ایجاد کنید ادامه دهید.
مهارتهایی که توسعه دادهاید، تازه شروع کار هستند. با فداکاری، خلاقیت و اشتیاق به یادگیری، شما در راه تبدیل شدن به یک توسعه دهنده وب ماهر هستید. وب بوم نقاشی شماست – پیش بروید و ایجاد کنید!
از اینکه با ما این سفر آموزشی را آغاز کردید متشکریم. در اینجا موفقیت مداوم شما در دنیای توسعه وب است!